Published on

SwiftUI-da Sheet va FullScreenCover β€” qanday ishlatish kerak

Authors

Bu videoda biz Sheet va FullScreenCover haqida gaplashamiz. Sheet β€” bu pastdan chiqib keladigan va joriy ekran ustiga qoplanadigan yangi ekran. Ko'rinishi juda professional va ilovalarda tez-tez ishlatiladi. FullScreenCover esa xuddi shunday ishlaydi, lekin ekranni to'liq qoplaydi.


Boshlang'ich sozlama β€” birinchi ekran

struct SheetsBootcamp: View {

    @State var showSheet: Bool = false

    var body: some View {
        ZStack {
            // Fon
            Color.green
                .edgesIgnoringSafeArea(.all)

            // Tugma
            Button {
                showSheet.toggle()
            } label: {
                Text("Tugma")
                    .foregroundColor(.green)
                    .font(.headline)
                    .padding(20)
                    .background(Color.white.cornerRadius(10))
            }
        }
        .sheet(isPresented: $showSheet) {
            Text("Salom!")
        }
    }
}

Tugma bosilganda showSheet true ga o'zgaradi va .sheet modifikatori pastdan yangi ekranni ko'rsatadi. Foydalanuvchi bu sheet-ni pastga siljitib ham yopishi mumkin.


Ikkinchi ekranni alohida View sifatida yaratish

Haqiqiy ilovalarda ikkinchi ekran odatda alohida faylda bo'ladi. Bu yerda misol uchun bitta faylda yaratamiz:

struct SecondScreen: View {

    @Environment(\.presentationMode) var presentationMode

    var body: some View {
        ZStack(alignment: .topLeading) {
            // Fon
            Color.red
                .edgesIgnoringSafeArea(.all)

            // Yopish tugmasi
            Button {
                presentationMode.wrappedValue.dismiss()
            } label: {
                Image(systemName: "xmark")
                    .foregroundColor(.white)
                    .font(.largeTitle)
            }
            .padding()
        }
    }
}

@Environment(\.presentationMode) β€” bu SwiftUI-ning maxsus o'zgaruvchisi. U joriy ekranning qanday ko'rsatilayotganini biladi va .dismiss() chaqirilganda to'g'ri usulda yopadi. Bu o'zgaruvchi nomini eslab qolish kerak β€” avtomatik to'ldirish ishlamaydi.


Sheet ichida ikkinchi ekranni ko'rsatish

struct SheetsBootcamp: View {

    @State var showSheet: Bool = false

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

            Button {
                showSheet.toggle()
            } label: {
                Text("Tugma")
                    .foregroundColor(.green)
                    .font(.headline)
                    .padding(20)
                    .background(Color.white.cornerRadius(10))
            }
        }
        .sheet(isPresented: $showSheet) {
            SecondScreen()
        }
    }
}

Natija: yashil birinchi ekran. Tugma bosilsa qizil ikkinchi ekran pastdan chiqadi. Ikkinchi ekrandagi "X" tugmasi yoki pastga siljitish orqali yopiladi.


Sheet-ni dismiss qilish β€” presentationMode

Sheet-ni kod orqali yopish uchun ikkinchi ekranga presentationMode qo'shish kerak:

struct SecondScreen: View {

    // Bu qatorni to'liq eslab qoling β€” autocomplete ishlamaydi
    @Environment(\.presentationMode) var presentationMode

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

            Button {
                // Sheet-ni yopish
                presentationMode.wrappedValue.dismiss()
            } label: {
                Image(systemName: "xmark")
                    .foregroundColor(.white)
                    .font(.largeTitle)
            }
            .padding()
        }
    }
}

FullScreenCover β€” ekranni to'liq qoplash

FullScreenCover xuddi Sheet kabi ishlaydi, lekin ekranni yuqorigacha to'liq qoplaydi va pastga siljitib yopib bo'lmaydi:

struct SheetsBootcamp: View {

    @State var showSheet: Bool = false

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

            Button {
                showSheet.toggle()
            } label: {
                Text("Tugma")
                    .foregroundColor(.green)
                    .font(.headline)
                    .padding(20)
                    .background(Color.white.cornerRadius(10))
            }
        }
        // Sheet o'rniga fullScreenCover
        .fullScreenCover(isPresented: $showSheet) {
            SecondScreen()
        }
    }
}

Sheet va FullScreenCover farqi

XususiyatSheetFullScreenCover
Ekranni qoplashQisman β€” yuqori chegara ko'rinadiTo'liq β€” yuqorigacha
Pastga siljitib yopishHaYo'q
DismisspresentationMode.wrappedValue.dismiss()Xuddi shu
IshlatishKo'proq keng tarqalganTo'liq qoplash kerak bo'lganda

⚠️ Muhim qoidalar

1. Bir view-da faqat bitta sheet

// ❌ NOTO'G'RI β€” ikki sheet birga ishlamaydi
.sheet(isPresented: $showSheet1) { ... }
.sheet(isPresented: $showSheet2) { ... }

// βœ… TO'G'RI β€” bitta sheet, bitta fullScreenCover ham emas
.sheet(isPresented: $showSheet) { ... }

2. Sheet ichiga shartli mantiq qo'ymang

// ❌ NOTO'G'RI β€” bu ishlamas va xatolarga olib keladi
.sheet(isPresented: $showSheet) {
    if someCondition {
        FirstView()
    } else {
        SecondView()
    }
}

// βœ… TO'G'RI β€” bitta view, kerak bo'lsa ma'lumot uzating
.sheet(isPresented: $showSheet) {
    SecondScreen()
}

Sheet modifikatori view yuklanishi bilanoq kontent yaratadi. Shuning uchun sheet ichidagi shartli mantiq to'g'ri yangilanmaydi va juda ko'p xatolarga sabab bo'ladi. Bu Stack Overflow-da eng ko'p so'raladigan muammolardan biri. Kelajakda bir sheet orqali bir nechta ekranni qanday ko'rsatish haqida alohida video bo'ladi.


Xulosa β€” 3 ta asosiy narsa

// 1. Sheet qo'shish β€” @State va binding
@State var showSheet: Bool = false

.sheet(isPresented: $showSheet) {
    SecondScreen()
}

// 2. Sheet-ni yopish β€” presentationMode
@Environment(\.presentationMode) var presentationMode
presentationMode.wrappedValue.dismiss()

// 3. Aslo sheet ichiga if/else qo'ymang!

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

Buy mea coffee