- Published on
SwiftUI crypto app — lazy yuklash uchun maxsus NavigationLink yaratish
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
SwiftUI crypto app — lazy yuklash uchun maxsus NavigationLink yaratish
Tangalar ro'yxatida biror qatorni bossak — o'sha tanga haqida batafsil ma'lumot ekraniga o'tishimiz kerak. Bu darsda biz navigatsiyani qo'shamiz, lekin SwiftUI-ning standart NavigationLink muammosini ko'rib chiqamiz va undan samaraliroq yechim taklif qilamiz.
1. DetailView yaratish
core/detail/views papkasida DetailView.swift faylini yaratamiz:
import SwiftUI
struct DetailView: View {
let coin: CoinModel
init(coin: CoinModel) {
self.coin = coin
print("DetailView ishga tushdi: \(coin.name)")
}
var body: some View {
Text(coin.name)
}
}
2. Standart NavigationLink muammosi
Avval oddiy usul bilan ulanib ko'ramiz — allCoinsList-dagi har bir qator uchun:
ForEach(vm.allCoins) { coin in
NavigationLink(destination: DetailView(coin: coin)) {
CoinRowView(coin: coin, showHoldingsColumn: false)
}
}
Bu ishlaydi, lekin muammo bor. Simulatorda qurilma konsolini ko'ring:
DetailView ishga tushdi: Bitcoin
DetailView ishga tushdi: Ethereum
DetailView ishga tushdi: Tether
DetailView ishga tushdi: BNB
... (250 ta)
Muammo:
NavigationLinkekranda ko'rinadigan har bir qator uchun darholDetailView-ni yaratadi! Demak biz hech narsaga bosmasdan oldin 250 taDetailViewyaratilib, ularninginitkodlari (keyinchalik API so'rovlari ham!) ishlaydi. Bu ilovani sekinlashtiradi.
3. Lazy Navigation — muammo yechimi
NavigationLink-ni orqa fonda yashiramiz va uni @State o'zgaruvchisi orqali boshqaramiz:
HomeView-da:
@State private var selectedCoin: CoinModel? = nil
@State private var showDetailView: Bool = false
body ichida fon sifatida navigatsiya havolasi:
var body: some View {
ZStack {
Color.theme.background.ignoresSafeArea()
VStack { /* Asosiy kontent */ }
}
.background(
// Ko'rinmas NavigationLink — faqat showDetailView=true bo'lganda faollashadi
NavigationLink(
destination: DetailLoadingView(coin: $selectedCoin),
isActive: $showDetailView,
label: { EmptyView() }
)
)
}
Qator bosilganda:
private func segue(coin: CoinModel) {
selectedCoin = coin
showDetailView.toggle()
}
Ro'yxatda:
ForEach(vm.allCoins) { coin in
CoinRowView(coin: coin, showHoldingsColumn: false)
.onTapGesture {
segue(coin: coin)
}
}
4. DetailLoadingView — oraliq yuklash
DetailView endi @Binding qabul qiluvchi DetailLoadingView orqali ochiladi:
struct DetailLoadingView: View {
@Binding var coin: CoinModel?
var body: some View {
ZStack {
// Faqat tanga mavjud bo'lganda — haqiqiy DetailView ochiladi
if let coin = coin {
DetailView(coin: coin)
}
}
}
}
DetailView-ni esa oddiy let bilan:
struct DetailView: View {
let coin: CoinModel
init(coin: CoinModel) {
self.coin = coin
print("Haqiqiy DetailView: \(coin.name)")
}
var body: some View {
Text(coin.name)
}
}
5. Nima yaxshilandi?
Endi simulatorda ilovani ishga tushiring va konsolga qarang:
// Ekran yuklanganida — hech narsa chop etilmaydi!
Bitta tangaga bosganda:
Haqiqiy DetailView: Bitcoin
Avval: barcha 250 ta
DetailViewbir vaqtda yaratilgan edi. Endi: faqat bosilgan tanga uchun, bosilgan vaqtda yaratiladi.Bu keyinchalik
DetailView-da API so'rovi bo'lganida juda muhim bo'ladi — aks holda 250 ta parallel API so'rovi yuborilgan bo'lardi!
6. CoinRowView-ni to'liq bosiladigan qilish
Muammo: qatorning o'rtasida Spacer() bor — u shaffof bo'lib, uni bosib bo'lmaydi. Shunchaki background-ga minimal shaffof rang qo'shamiz:
// CoinRowView.swift
var body: some View {
HStack { /* ... */ }
.background(Color.theme.background.opacity(0.001))
// opacity 0.001 = ko'rinmaydi, lekin bosish uchun uyga ega
}
Nima uchun 0.001?
opacity: 0— element mavjud emas, bosib bo'lmaydi.opacity: 0.001— ko'rinmaydi lekin ekranda mavjud, shuning uchun.onTapGestureishlaydi.
Portfolio ro'yxatiga ham
portfolioCoinsList-da ham xuddi shunday:
ForEach(vm.portfolioCoins) { coin in
CoinRowView(coin: coin, showHoldingsColumn: true)
.onTapGesture {
segue(coin: coin)
}
}
Xulosa
| Usul | Kamchiligi | Afzalligi |
|---|---|---|
Standart NavigationLink | Barcha viewlarni oldindan yaratadi | Tez navigatsiya |
Lazy NavigationLink | Biroz ko'proq kod | Faqat kerakli view yaratiladi |
Hozircha DetailView faqat tanga nomini ko'rsatadi. Keyingi darslarda biz uni to'ldirish bilan shug'ullanamiz. 🚀