Grid Layout
1. LazyVGrid
Phần tiêu đề “1. LazyVGrid”Cơ bản
Phần tiêu đề “Cơ bản”let columns = [ GridItem(.flexible()), GridItem(.flexible())]
LazyVGrid(columns: columns, spacing: 16) { ForEach(0..<10) { index in RoundedRectangle(cornerRadius: 8) .fill(.blue) .frame(height: 100) .overlay(Text("\(index)").foregroundColor(.white)) }}.padding()GridItem Types
Phần tiêu đề “GridItem Types”// Fixed widthGridItem(.fixed(100))
// Flexible (min đến max)GridItem(.flexible(minimum: 80, maximum: 150))
// Adaptive (tự động fit nhiều items)GridItem(.adaptive(minimum: 100))2. Grid Examples
Phần tiêu đề “2. Grid Examples”2 Columns Fixed
Phần tiêu đề “2 Columns Fixed”let columns = [ GridItem(.fixed(150)), GridItem(.fixed(150))]3 Columns Flexible
Phần tiêu đề “3 Columns Flexible”let columns = Array(repeating: GridItem(.flexible()), count: 3)Adaptive (Auto-fit)
Phần tiêu đề “Adaptive (Auto-fit)”let columns = [ GridItem(.adaptive(minimum: 100, maximum: 150))]3. LazyHGrid
Phần tiêu đề “3. LazyHGrid”let rows = [ GridItem(.fixed(60)), GridItem(.fixed(60))]
ScrollView(.horizontal) { LazyHGrid(rows: rows, spacing: 12) { ForEach(0..<20) { index in RoundedRectangle(cornerRadius: 8) .fill(.orange) .frame(width: 80) .overlay(Text("\(index)").foregroundColor(.white)) } } .padding()}4. Spacing và Alignment
Phần tiêu đề “4. Spacing và Alignment”let columns = [ GridItem(.flexible(), spacing: 8), GridItem(.flexible())]
LazyVGrid( columns: columns, alignment: .center, spacing: 16 // Vertical spacing) { // Items}5. Grid (iOS 16+)
Phần tiêu đề “5. Grid (iOS 16+)”Non-lazy grid cho layout nhỏ.
Grid { GridRow { Text("Row 1, Col 1") Text("Row 1, Col 2") Text("Row 1, Col 3") }
GridRow { Text("Row 2, Col 1") Text("Row 2, Col 2") Text("Row 2, Col 3") }}Grid với Alignment
Phần tiêu đề “Grid với Alignment”Grid(alignment: .leading, horizontalSpacing: 12, verticalSpacing: 8) { GridRow { Text("Name:") Text("John Doe") .gridColumnAlignment(.trailing) }
GridRow { Text("Email:") }}Spanning Columns
Phần tiêu đề “Spanning Columns”Grid { GridRow { Text("Header") .gridCellColumns(2) // Span 2 columns }
GridRow { Text("Left") Text("Right") }}6. Photo Grid
Phần tiêu đề “6. Photo Grid”struct PhotoGrid: View { let photos = Array(1...12)
let columns = [ GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible()) ]
var body: some View { ScrollView { LazyVGrid(columns: columns, spacing: 2) { ForEach(photos, id: \.self) { photo in Rectangle() .fill(.gray.opacity(0.3)) .aspectRatio(1, contentMode: .fill) .overlay( Image(systemName: "photo") .foregroundColor(.gray) ) } } } }}7. Product Grid
Phần tiêu đề “7. Product Grid”struct Product: Identifiable { let id = UUID() let name: String let price: Double}
struct ProductGrid: View { let products: [Product]
let columns = [ GridItem(.adaptive(minimum: 160)) ]
var body: some View { ScrollView { LazyVGrid(columns: columns, spacing: 16) { ForEach(products) { product in VStack(alignment: .leading) { RoundedRectangle(cornerRadius: 8) .fill(.gray.opacity(0.2)) .aspectRatio(1, contentMode: .fill)
Text(product.name) .font(.headline)
Text("$\(product.price, specifier: "%.2f")") .foregroundColor(.gray) } } } .padding() } }}8. Calendar Grid
Phần tiêu đề “8. Calendar Grid”struct CalendarGrid: View { let days = Array(1...31) let columns = Array(repeating: GridItem(.flexible()), count: 7)
var body: some View { VStack { // Header LazyVGrid(columns: columns) { ForEach(["S", "M", "T", "W", "T", "F", "S"], id: \.self) { day in Text(day) .font(.caption) .foregroundColor(.gray) } }
// Days LazyVGrid(columns: columns, spacing: 8) { ForEach(days, id: \.self) { day in Text("\(day)") .frame(width: 36, height: 36) .background( Circle() .fill(day == 15 ? .blue : .clear) ) .foregroundColor(day == 15 ? .white : .primary) } } } .padding() }}9. Section Headers
Phần tiêu đề “9. Section Headers”LazyVGrid(columns: columns, pinnedViews: [.sectionHeaders]) { Section { ForEach(0..<6) { _ in RoundedRectangle(cornerRadius: 8) .fill(.blue) .frame(height: 100) } } header: { Text("Section 1") .font(.headline) .frame(maxWidth: .infinity, alignment: .leading) .padding() .background(.white) }
Section { ForEach(0..<6) { _ in RoundedRectangle(cornerRadius: 8) .fill(.green) .frame(height: 100) } } header: { Text("Section 2") .font(.headline) .frame(maxWidth: .infinity, alignment: .leading) .padding() .background(.white) }}📝 Tóm tắt
Phần tiêu đề “📝 Tóm tắt”| GridItem | Mô tả |
|---|---|
.fixed(size) |
Kích thước cố định |
.flexible() |
Co giãn trong khoảng |
.adaptive() |
Tự động fit nhiều items |
| Component | Mục đích |
|---|---|
LazyVGrid |
Grid dọc, lazy load |
LazyHGrid |
Grid ngang, lazy load |
Grid |
Non-lazy, iOS 16+ |