Published on

SwiftUI-da Sheet, Transition va Offset bilan Popover yaratish

Authors

Bu videoda yangi narsa o'rganmaymiz β€” aksincha, oldingi videolarda o'rgangan narsalarimizni mustahkamlaymiz. Maqsad: yangi ekranni ko'rsatishning uch xil usulini ko'rish va har birining qachon yaxshiroq ekanini tushunish.

Uch usul:

  • Sheet β€” avvalgi videoda o'rgandik
  • Transition β€” avvalgi videoda o'rgandik
  • Offset animatsiyasi β€” avvalgi videoda o'rgandik

Uchala usul ham bir xil natija beradi. Dasturchi sifatida qaysi usul ilovangizga mos kelishini o'zingiz tanlaysiz.


Asosiy sozlama β€” birinchi va ikkinchi ekran

struct PopoverBootcamp: View {

    @State var showNewScreen: Bool = false

    var body: some View {
        ZStack {
            // Birinchi ekran foni
            Color.orange
                .edgesIgnoringSafeArea(.all)

            VStack {
                Button("Tugma") {
                    showNewScreen.toggle()
                }
                .font(.largeTitle)
                Spacer()
            }
        }
    }
}

// Ikkinchi ekran
struct NewScreen: View {

    @Binding var showNewScreen: Bool
    @Environment(\.presentationMode) var presentationMode

    var body: some View {
        ZStack(alignment: .topLeading) {
            Color.purple
                .edgesIgnoringSafeArea(.all)

            Button {
                showNewScreen = false
                presentationMode.wrappedValue.dismiss()
            } label: {
                Image(systemName: "xmark")
                    .foregroundColor(.white)
                    .font(.largeTitle)
                    .padding()
            }
        }
    }
}

1-usul: Sheet

Eng oddiy va keng tarqalgan usul. .sheet modifikatori pastdan yangi ekranni ko'rsatadi:

struct PopoverBootcamp: View {

    @State var showNewScreen: Bool = false

    var body: some View {
        ZStack {
            Color.orange
                .edgesIgnoringSafeArea(.all)

            VStack {
                Button("Tugma") {
                    showNewScreen.toggle()
                }
                .font(.largeTitle)
                Spacer()
            }
        }
        // 1-USUL: Sheet
        .sheet(isPresented: $showNewScreen) {
            NewScreen(showNewScreen: $showNewScreen)
        }
    }
}

Afzalligi: Oddiy va tushinarli. Mantiqiy β€” yangi ekranga o'tish = yangi sheet.

Kamchiligi: Faqat standart animatsiya. Ikkinchi ekranda bo'lganingizda siz yangi muhitdasiz β€” asosiy ekran ustiga narsa qo'shib bo'lmaydi.


2-usul: Transition

if sharti bilan ekranni view hierarchy-ga qo'shish va olib tashlash. Sheet-ga o'xshash ko'rinish, lekin ko'proq moslashuvchanlik:

struct PopoverBootcamp: View {

    @State var showNewScreen: Bool = false

    var body: some View {
        ZStack {
            Color.orange
                .edgesIgnoringSafeArea(.all)

            VStack {
                Button("Tugma") {
                    withAnimation(.spring()) {
                        showNewScreen.toggle()
                    }
                }
                .font(.largeTitle)
                Spacer()
            }

            // 2-USUL: Transition
            // ZStack va zIndex kerak β€” ikkinchi ekran har doim ustida bo'lishi uchun
            ZStack {
                if showNewScreen {
                    NewScreen(showNewScreen: $showNewScreen)
                        .padding(.top, 100)
                        .transition(.move(edge: .bottom))
                }
            }
            .zIndex(2.0)
        }
    }
}

Muhim: zIndex(2.0) qo'shmasangiz, ikkinchi ekran chiqayotganda to'g'ri ko'rinmasligi mumkin β€” asosiy ekran ustiga chiqmasligi yoki animatsiya noto'g'ri ishlashi mumkin.

NewScreen-da esa presentationMode o'rniga @Binding orqali dismiss:

struct NewScreen: View {

    @Binding var showNewScreen: Bool

    var body: some View {
        ZStack(alignment: .topLeading) {
            Color.purple
                .edgesIgnoringSafeArea(.all)

            Button {
                withAnimation(.spring()) {
                    showNewScreen = false  // Binding orqali yopish
                }
            } label: {
                Image(systemName: "xmark")
                    .foregroundColor(.white)
                    .font(.largeTitle)
                    .padding()
            }
        }
    }
}

Afzalligi: Animatsiyani to'liq o'zingiz belgilaysiz. Asosiy ekran ustiga narsalar qo'shish mumkin β€” hali ham bir xil view-dasiz.

Kamchiligi: zIndex bilan ishlash, @Binding qo'shish zarur β€” biroz murakkabroq.


3-usul: Offset animatsiyasi

Ikkinchi ekran doim view hierarchy-da mavjud, lekin offset orqali ekran pastida yashirinadi. Tugma bosilganda offset nolga keladi:

struct PopoverBootcamp: View {

    @State var showNewScreen: Bool = false

    var body: some View {
        ZStack {
            Color.orange
                .edgesIgnoringSafeArea(.all)

            VStack {
                Button("Tugma") {
                    showNewScreen.toggle()
                }
                .font(.largeTitle)
                Spacer()
            }

            // 3-USUL: Offset animatsiyasi
            NewScreen(showNewScreen: $showNewScreen)
                .padding(.top, 100)
                .offset(y: showNewScreen ? 0 : UIScreen.main.bounds.height)
                // showNewScreen true bo'lsa β€” joyida (offset 0)
                // false bo'lsa β€” ekran pastiga suriladi (ko'rinmaydi)
                .animation(.spring())
        }
    }
}

Afzalligi: Eng ko'p moslashuvchanlik. Animatsiyani to'liq boshqarish mumkin. Asosiy ekranda hamma narsa qo'llash mumkin.

Kamchiligi: Ikkinchi ekran view hierarchy-da doim mavjud β€” katta va murakkab ekranlar uchun unumdorlikka ta'sir qilishi mumkin.


Uch usulni solishtirish

XususiyatSheetTransitionOffset
Soddalikβœ… Eng oddiy⚠️ O'rtacha⚠️ O'rtacha
Animatsiyani sozlash❌ Faqat standartβœ… To'liqβœ… To'liq
Asosiy ekran ustiga qo'shish❌ Yangi muhitβœ… Mumkinβœ… Mumkin
Dismiss usulipresentationMode@Binding@Binding
zIndex kerakmiYo'qβœ… KerakYo'q

Qaysi usulni tanlash kerak?

  • Sheet β€” oddiy ekranga o'tish, ko'p sozlash kerak bo'lmaganda
  • Transition β€” animatsiyani o'zingiz belgilash, asosiy ekranda qo'shimcha narsa ko'rsatish kerak bo'lganda
  • Offset β€” eng ko'p moslashuvchanlik kerak bo'lganda, lekin ikkinchi ekran oddiy bo'lganda

Transition usuli ko'proq tavsiya etiladi β€” u eng dinamik va moslashuvchan. Sheet eng oddiy, lekin animatsiyani o'zgartirish imkoni cheklangan.

Swift UI-ning kuchli tomoni shundaki β€” bir xil natijaga erishishning bir nechta yo'li bor. Tajriba oshgan sari qaysi usul qachon yaxshiroq ekanini o'zingiz his qila boshlaysiz.

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

Buy mea coffee