Published on

SwiftUI-da AnyLayout

Authors

Bu videoda SwiftUI-dagi Layout protokoli va AnyLayout bilan tanishamiz. VStack va HStack kabi barcha stack turlari Layout protokoliga mos keladi. AnyLayout esa β€” bu turli xil layout-larni bitta o'zgaruvchida saqlash imkonini beruvchi "type-erased" (tur o'chirilgan) tur. Bu qurilma yo'nalishi yoki ekran o'lchamiga qarab layout-ni dinamik almashtirish uchun ishlatiladi.


Yangi fayl yaratish

Navigatorda o'ng tugma bosib yangi SwiftUI fayli yarating. Uni AnyLayoutBootcamp deb nomlang va Create tugmasini bosing.


Size Class nima?

iOS-da har bir qurilma ekrani horizontal va vertical size class-ga ega. Ularning qiymati ikkita bo'lishi mumkin:

  • .compact β€” kichik bo'sh joy
  • .regular β€” katta bo'sh joy

Bu qiymatlarni environment orqali olish mumkin:

struct AnyLayoutBootcamp: View {

    @Environment(\.horizontalSizeClass) private var horizontalSizeClass
    @Environment(\.verticalSizeClass) private var verticalSizeClass

    var body: some View {
        VStack {
            Text("Gorizontal: \(horizontalSizeClass.debugDescription)")
            Text("Vertikal: \(verticalSizeClass.debugDescription)")
        }
    }
}

Muhim eslatma

Size class qurilma yo'nalishiga (portret/albom) to'g'ridan-to'g'ri bog'liq emas. Masalan:

  • iPhone 14 Pro β€” albom rejimida ham horizontalSizeClass hamon .compact bo'lib qoladi
  • iPhone 14 Pro Max β€” albom rejimida horizontalSizeClass .regular bo'ladi
  • iPad β€” odatda .regular

Shuning uchun qurilma yo'nalishiga emas, balki size class qiymatiga e'tibor qaratish to'g'riroq yondashuv.


Oddiy shartli yondashuv β€” if-else

Avval an'anaviy if-else bilan ko'ramiz:

struct AnyLayoutBootcamp: View {

    @Environment(\.horizontalSizeClass) private var horizontalSizeClass

    var body: some View {
        if horizontalSizeClass == .compact {
            VStack {
                Text("Alpha")
                Text("Beta")
                Text("Gamma")
            }
        } else {
            HStack {
                Text("Alpha")
                Text("Beta")
                Text("Gamma")
            }
        }
    }
}

Bu ishlaydi, lekin har bir holat uchun kodni ikki marta yozish kerak. Murakkab ekranlarda bu noqulay bo'lib qoladi.


AnyLayout bilan toza yechim

AnyLayout yordamida kontentni faqat bir marta yozib, faqat layout turini almashtirish mumkin:

struct AnyLayoutBootcamp: View {

    @Environment(\.horizontalSizeClass) private var horizontalSizeClass

    var body: some View {
        let layout: AnyLayout = horizontalSizeClass == .compact
            ? AnyLayout(VStackLayout())
            : AnyLayout(HStackLayout())

        layout {
            Text("Alpha")
            Text("Beta")
            Text("Gamma")
        }
    }
}

Bu yerda:

  • AnyLayout β€” turi e'lon qilingan o'zgaruvchi, ichida VStackLayout yoki HStackLayout saqlanishi mumkin
  • VStackLayout() / HStackLayout() β€” VStack va HStack-ning rasmiy "layout" versiyalari
  • Ternary operator orqali shart asosida tanlangan layout layout o'zgaruvchisiga yoziladi
  • Kontent (Text("Alpha"), Text("Beta"), Text("Gamma")) faqat bir marta yoziladi

Qanday ishlaydi?

horizontalSizeClass qiymati o'zgarganda (masalan, foydalanuvchi qurilmani aylantirganda yoki ilova oynasi kattalashtirilganda):

  • .compact bo'lsa β€” kontent VStack ichida vertikal joylashadi
  • .regular bo'lsa β€” kontent HStack ichida gorizontal joylashadi

Bu o'zgarish real vaqtda sodir bo'ladi β€” environment qiymati yangilanishi bilan view avtomatik qayta chiziladi.


To'liq kod

struct AnyLayoutBootcamp: View {

    @Environment(\.horizontalSizeClass) private var horizontalSizeClass
    @Environment(\.verticalSizeClass) private var verticalSizeClass

    var body: some View {
        VStack(spacing: 12) {
            Text("Gorizontal: \(horizontalSizeClass.debugDescription)")
            Text("Vertikal: \(verticalSizeClass.debugDescription)")

            let layout: AnyLayout = horizontalSizeClass == .compact
                ? AnyLayout(VStackLayout())
                : AnyLayout(HStackLayout())

            layout {
                Text("Alpha")
                Text("Beta")
                Text("Gamma")
            }
        }
    }
}

Qachon ishlatish kerak?

AnyLayout quyidagi holatlarda foydali:

  • Ekran murakkab bo'lib, bir xil kontentni ikki marta yozish noqulay bo'lsa
  • iPad va iPhone uchun bitta kodda ikki xil layout kerak bo'lsa
  • Qurilma aylantirilganda layout dinamik o'zgarishi kerak bo'lsa

Agar ilovangiz faqat bitta layout bilan barcha qurilmalarda yaxshi ishlasa, AnyLayout-ga ehtiyoj yo'q β€” bu faqat moslashuvchan dizayn zarur bo'lgan holatlar uchun vosita.


Xulosa

Bu videoda o'rgandik:

  • horizontalSizeClass va verticalSizeClass β€” environment orqali olinadigan, qurilma bo'sh joyini bildiruvchi qiymatlar (.compact yoki .regular)
  • Size class qurilma yo'nalishiga emas, balki haqiqiy ekran o'lchamiga bog'liq
  • AnyLayout β€” turli layout turlarini (VStackLayout, HStackLayout) bitta o'zgaruvchida saqlash imkonini beruvchi tur
  • AnyLayout yordamida kontentni bir marta yozib, faqat layout turini shartli almashtirish mumkin
  • O'zgarish real vaqtda sodir bo'ladi β€” qurilma aylantirilganda yoki oyna o'lchami o'zgarganda
Buy mea coffee