Published on

SwiftUI-da LazyVGrid, LazyHGrid va GridItem-lardan qanday foydalanish kerak

Authors

Hammaga xush kelibsiz! Bu videoda biz Grid-lar haqida gaplashamiz. Grid deganda xayolingizga Instagram profili kelishi mumkin — pastda uchta ustunda joylashgan rasmlar to'plami. Xuddi shunday ko'rinishni SwiftUI-da bir necha qator kod bilan yasash mumkin.

Grid-lar SwiftUI-ga nisbatan yangi qo'shilgan komponent va dastlab ularni to'g'ri ishlatish unchalik aniq ko'rinmaydi. Shuning uchun ko'plab yangi dasturchilar ularni e'tiborsiz qoldirib, kam ishlatadilar. Bu videoda Grid-larni to'liq o'rganamiz — ustunlarni moslashtirish, har xil qurilmalarda moslashuvchan ko'rinish va boshqa imkoniyatlar.


Lazy — bu nima?

SwiftUI-dagi barcha Grid-lar avtomatik ravishda lazy (dangasa) bo'ladi. Bu bizga dasturchi sifatida juda qulay, chunki:

  • Agar Grid-da minglab element bo'lsa ham, faqat ekranda ko'rinadigan yoki ekranga yaqinlashib kelayotgan elementlar yaratiladi
  • Agar lazy bo'lmaganda, minglab elementning barchasi bir vaqtda yaratilgan bo'lar edi va bu ilovani sekinlashtirardi

Grid-lar lazy bo'lgani uchun ilova tez va samarali ishlaydi.


Yangi fayl yaratish

Xcode-da yangi SwiftUI View fayli yarating va uni GridBootcamp deb nomlang.


LazyVGrid — asosiy tushuncha

LazyVGrid — bu vertikal yo'nalishda rivojlanadigan Grid. U columns parametri sifatida [GridItem] — ya'ni GridItem-lar massivini oladi.

struct GridBootcamp: View {

    let columns: [GridItem] = [
        GridItem(.fixed(50), spacing: nil, alignment: nil),
    ]

    var body: some View {
        LazyVGrid(columns: columns) {
            ForEach(0..<50) { index in
                Rectangle()
                    .frame(height: 50)
            }
        }
    }
}

Bu yerda bitta ustun bor va u fixed(50) — ya'ni kengligi 50 piksel bilan qotirib qo'yilgan.


GridItem turlari — Fixed, Flexible, Adaptive

1. Fixed — qat'iy o'lcham

let columns: [GridItem] = [
    GridItem(.fixed(50)),   // 50 piksel keng, o'zgarmaydi
    GridItem(.fixed(100)),  // 100 piksel keng
    GridItem(.fixed(75)),   // 75 piksel keng
]

Har bir GridItem massivdagi bir ustunni ifodalaydi. Ko'proq GridItem qo'shsangiz — ko'proq ustun hosil bo'ladi:

// 5 ta teng ustun
let columns: [GridItem] = [
    GridItem(.fixed(50)),
    GridItem(.fixed(50)),
    GridItem(.fixed(50)),
    GridItem(.fixed(50)),
    GridItem(.fixed(50)),
]

2. Flexible — moslashuvchan o'lcham

let columns: [GridItem] = [
    GridItem(.flexible()),
    GridItem(.flexible()),
    GridItem(.flexible()),
]

flexible — eng ko'p ishlatiladigan tur. Ustunlar mavjud bo'shliqqa qarab avtomatik o'lchamini moslaydi. Telefon yoki planshet, har qanday ekran o'lchamida to'g'ri ko'rinadi. Minimol va maksimal o'lcham ham belgilash mumkin, lekin ko'pincha shunchaki .flexible() yetarli.

3. Adaptive — moslashuvchi to'ldiruvchi

let columns: [GridItem] = [
    GridItem(.adaptive(minimum: 50, maximum: 300)),
]

adaptive — bitta ustun ichiga imkon boricha ko'proq element sig'diradi. Masalan, minimum 50 va maksimum 300 desangiz, ustun kengligiga qarab 3, 4 yoki 5 ta element sig'dirishi mumkin.

// Ikki adaptive ustun — chap ustun kichik, o'ng ustun kattaroq
let columns: [GridItem] = [
    GridItem(.adaptive(minimum: 50, maximum: 300)),
    GridItem(.adaptive(minimum: 150, maximum: 300)),
]

Bu tur onlaynda ko'p maqtaladi, lekin amalda flexible ancha qulay va keng tarqalgan.


ForEach bilan ishlatish

Grid-lar odatda ForEach bilan birgalikda ishlatiladi:

struct GridBootcamp: View {

    let columns: [GridItem] = [
        GridItem(.flexible()),
        GridItem(.flexible()),
        GridItem(.flexible()),
    ]

    var body: some View {
        LazyVGrid(columns: columns) {
            ForEach(0..<50) { index in
                Rectangle()
                    .frame(height: 50)
            }
        }
    }
}

ScrollView bilan birga ishlatish — haqiqiy dunyo misoli

Instagram profili sahifasiga o'xshash ko'rinish yaratish:

struct GridBootcamp: View {

    let columns: [GridItem] = [
        GridItem(.flexible()),
        GridItem(.flexible()),
        GridItem(.flexible()),
    ]

    var body: some View {
        ScrollView {
            // Profil qismi (yuqoridagi sarlavha)
            Rectangle()
                .fill(Color.white)
                .frame(height: 400)

            // Rasmlar grid-i
            LazyVGrid(columns: columns) {
                ForEach(0..<50) { index in
                    Rectangle()
                        .frame(height: 150)
                }
            }
        }
    }
}

Bu xuddi Instagram profilining shablo니 — yuqorida profil ma'lumotlari, pastda uchta ustunda rasmlar, va scroll qilish imkoniyati.


Spacing — intervallarni boshqarish

Grid-da ikkita xil interval bor:

  1. Qatorlar orasidagi intervalLazyVGrid-ning spacing parametri
  2. Ustunlar orasidagi interval — har bir GridItem-ning spacing parametri
struct GridBootcamp: View {

    let columns: [GridItem] = [
        GridItem(.flexible(), spacing: 6),   // ustunlar orasida 6 piksel
        GridItem(.flexible(), spacing: 6),
        GridItem(.flexible(), spacing: 6),
    ]

    var body: some View {
        ScrollView {
            LazyVGrid(
                columns: columns,
                alignment: .center,
                spacing: 6,           // qatorlar orasida 6 piksel
                pinnedViews: []
            ) {
                ForEach(0..<50) { index in
                    Rectangle()
                        .frame(height: 150)
                }
            }
        }
    }
}

Intervallarni o'zgartirish misollari:

// Hamma interval nol
LazyVGrid(columns: columns, spacing: 0) { ... }

// Katta interval
LazyVGrid(columns: columns, spacing: 50) { ... }

// Standart (tavsiya etilgan)
LazyVGrid(columns: columns, spacing: 6) { ... }

Section va Pinned Header-lar

Grid ichida bo'limlarni Section bilan ajratish mumkin:

struct GridBootcamp: View {

    let columns: [GridItem] = [
        GridItem(.flexible(), spacing: 6),
        GridItem(.flexible(), spacing: 6),
        GridItem(.flexible(), spacing: 6),
    ]

    var body: some View {
        ScrollView {
            Rectangle()
                .fill(Color.orange)
                .frame(height: 400)

            LazyVGrid(
                columns: columns,
                spacing: 6,
                pinnedViews: [.sectionHeaders]  // sarlavhalarni yuqorida qotirib qo'yish
            ) {
                // Birinchi bo'lim
                Section(header:
                    Text("Bo'lim 1")
                        .font(.title)
                        .foregroundColor(.white)
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .background(Color.blue)
                        .padding()
                ) {
                    ForEach(0..<20) { index in
                        Rectangle()
                            .frame(height: 150)
                    }
                }

                // Ikkinchi bo'lim
                Section(header:
                    Text("Bo'lim 2")
                        .font(.title)
                        .foregroundColor(.white)
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .background(Color.red)
                        .padding()
                ) {
                    ForEach(0..<20) { index in
                        Rectangle()
                            .fill(Color.green)
                            .frame(height: 150)
                    }
                }
            }
        }
    }
}

pinnedViews: [.sectionHeaders] — bu parametr bo'lim sarlavhasini scroll qilayotganda ekranning yuqorisiga qotirib qo'yadi. Siz 1-bo'limda aylanayotganda "Bo'lim 1" sarlavhasi doim ko'rinib turadi, 2-bo'limga o'tganda esa "Bo'lim 2" ko'rinadi. Ilovlarda bu juda qulay va tez-tez ishlatiladigan effekt.


LazyHGrid — gorizontal Grid

LazyHGrid — bu LazyVGrid-ning gorizontal versiyasi. Farqi minimal:

let rows: [GridItem] = [
    GridItem(.flexible()),
    GridItem(.flexible()),
    GridItem(.flexible()),
]

ScrollView(.horizontal) {
    LazyHGrid(rows: rows) {
        ForEach(0..<50) { index in
            Rectangle()
                .frame(width: 150)
        }
    }
}

Asosiy farqlar:

  • columns o'rniga rows parametri
  • ScrollView-ni gorizontal qilish kerak .horizontal

Xulosa

GridItem turiQachon ishlatish
.fixed(n)Aniq piksel o'lcham kerak bo'lganda
.flexible()Ekran o'lchamiga moslashuvchi ustun kerak bo'lganda (eng keng tarqalgan)
.adaptive(minimum:)Bitta ustunda imkon qadar ko'proq element sig'dirish kerak bo'lganda

Grid-lar deyarli har doim ScrollView va ForEach bilan birgalikda ishlatiladi. Section va pinnedViews yordamida professional ko'rinishdagi ro'yxatlar yaratish mumkin.

Rahmat, men Nick, bu Swiftful Thinking va keyingi videoda ko'rishguncha!

Buy mea coffee