Published on

SwiftfulRouting: SwiftUI'da navigatsiyani inqilobiy boshqarish

Authors

Nega SwiftUI navigatsiyasi asabni buzadi?

SwiftUI'da bir ekrandan ikkinchisiga o'tish (routing) ancha murakkab ko'rinishga ega. Ayniqsa ilovangiz kattalashgan sari, NavigationLink, .sheet, .fullScreenCover, va .alert larni har bir faylda yozish kodni tartibsiz qilib yuboradi.

Qolaversa, UIKit'dan farqli o'laroq, SwiftUI'da navigatsiyani View model (MVVM) ichida boshqarish judayam qiyin masala.

Mening SwiftfulRouting paketim bularning barchasiga chek qo'yadi. Siz butun ilovangiz davomida biron marta NavigationStack ham, .sheet ham ishlatmaysiz!

1. O'rnatish va Asosiy sozlama

Paketni odatdagidek GitHub orqali o'rnatamiz: https://GitHub.com/SwiftfulThinking/SwiftfulRouting

Ilovani yoki modulni boshlayotganda eng birinchi qiladigan ishimiz — uni RouterView ichiga o'rash:

import SwiftUI
import SwiftfulRouting

struct ContentView: View {
    var body: some View {
        // NavigationStack o'rniga faqat RouterView ishlatiladi
        RouterView { router in
            HomeView()
        }
    }
}

2. Navigatsiya qanday ishlaydi?

RouterView ichidagi har qanday oyna endi router obyektiga avtomatik ulanadi. Uni chaqirish uchun @Environment(\.router) dan foydalanamiz:

struct HomeView: View {
    @Environment(\.router) var router

    var body: some View {
        VStack {
            Text("Bosh Sahifa")

            Button("Keyingi ekranga o'tish") {
                // Yangi ekranga push qilish (ochish)
                router.showScreen(.push) {
                    SecondScreen()
                }
            }

            Button("Modal (Sheet) ochish") {
                // Ekranni pastdan tepaga chiqarish
                router.showScreen(.sheet) {
                    ProfileScreen()
                }
            }

            Button("Ogohlantirish (Alert) chiqarish") {
                // Oddiy ogohlantirish oynasi
                router.showAlert(.alert, title: "Diqqat!", subtitle: "Haqiqatan ham o'chirmoqchimisiz?") {
                    Button("Ha", role: .destructive) { }
                    Button("Yo'q", role: .cancel) { }
                }
            }
        }
    }
}

Ko'rib turganingizdek, endi hech qanday state variable'lar (@State var showSheet = false) kerak emas. Barchasi router ni chaqirish bilan ishlaydi! Oynani yopish uchun esa shunchaki router.dismissScreen() ni yozish yetarli.

3. MVVM bilan ajoyib kombinatsiya

Agar siz navigatsiyani View ichida emas, balki ViewModel (yoki Presenter/Router) ichida boshqarmoqchi bo'lsangiz, router o'zgaruvchisini to'g'ridan-to'g'ri uzatishingiz mumkin:

class HomeViewModel: ObservableObject {
    let router: AnyRouter

    init(router: AnyRouter) {
        self.router = router
    }

    func onButtonTap() {
        // Butun biznes mantiq shu yerda
        router.showScreen(.push) {
            SecondScreen()
        }
    }
}

Bu sizga Viper, MVVM-C kabi murakkab arxitekturalarni SwiftUI bilan mukammal birlashtirish imkonini beradi.

Xulosa

SwiftfulRouting — men o'z loyihalarimda eng ko'p ishlatadigan vositam. Unda ekranlarni birdaniga guruh qilib push qilish (Stack of screens), AB-testing uchun maxsus Screen Flows, va bir-birining ustiga ochiluvchi cheksiz modallar (modals) kabi juda chuqur darajadagi funksiyalar bor. Agar ilovangiz kattalashishni boshlasa, uni albatta sinab ko'ring!

Buy mea coffee