List — SwiftUI-da ma'lumotlarni vertikal aylantiriladigan ro'yxat ko'rinishida ko'rsatish uchun konteyner View, UIKit-dagi UITableView ning analogidir. Apple Developer Documentation, 2024 ga ko'ra, List statik va dinamik bo'limlarni, surish harakatlarini, qatorlarni sudrab olib yurishni va pull-to-refresh-ni qo'llab-quvvatlaydi. UITableView-dan farqli o'laroq, List SwiftUI va ForEach-ga asoslangan deklarativ API dan foydalanadi, hujayralarni qayta ishlatish va ko'p sonli qatorlar bilan ishlashda unumdorlikni avtomatik boshqaradi.
Asosiy fikrlar
List — elementlar ketma-ketligini vertikal aylantiriladigan ro'yxatda ko'rsatadigan View. U iOS 13 bilan birga SwiftUI-da paydo bo'ldi va UIKit-dagi UITableView o'rnini bosuvchi ma'lumotlar ro'yxatlarini ko'rsatishning asosiy usulidir. List hujayralarni qayta ishlatish, aylantirish va unumdorlikni avtomatik boshqaradi.
List lazy-loading dan foydalanadi: hujayralar aylantirish jarayonida yaratiladi, hammasi birdaniga emas. Bu uni ScrollView ichidagi VStack bilan ForEach dan farqlaydi, bunda barcha hujayralar renderlash vaqtida yaratiladi. List shuningdek surish harakatlari, pull-to-refresh, tahrirlash (o'chirish/ko'chirish) va qatorlarni tanlash uchun o'rnatilgan qo'llab-quvvatlashni ta'minlaydi.
Apple WWDC 2021 (Session 10072) ga ko'ra, iOS 15+ da List kolleksiya darajasida yangi diffing mexanizmi tufayli sezilarli unumdorlik yaxshilanishlarini oldi. Bu List-ni ma'lumotlarni yangilashda, ayniqsa yuzlab qatorli ro'yxatlar uchun samaraliroq qildi.
Dasturchilar ko'pincha View-lar to'plamini ko'rsatish uchun List va ScrollView + VStack o'rtasida tanlov qiladilar. Asosiy farq: List hujayralarni qayta ishlatishdan foydalanadi (UITableView kabi), ScrollView + VStack esa barcha View-larni birdaniga yaratadi. Ruxsat etilgan sonli elementlar (20 gacha) bo'lgan ro'yxatlar uchun farq ahamiyatsiz. 50+ qatorli dinamik ro'yxatlar uchun List unumdorlik jihatidan afzal.
Statik List — to'g'ridan-to'g'ri List tanasida belgilangan qat'iy sonli qatorlarga ega ro'yxat. Ma'lum elementlar to'plamiga ega menyular, sozlamalar va shakllar uchun ishlatiladi. Har bir qator tsikl yoki ForEachsiz aniq e'lon qilinadi.
// Statik ro'yxat (menyu va sozlamalar uchun)
List {
Text("Profil")
Text("Sozlamalar")
Text("Haqida")
}
// Dinamik ro'yxat (ma'lumotlar uchun)
struct UserList: View {
let users: [User]
var body: some View {
List(users) { user in
HStack {
Text(user.name)
Text(user.role)
.foregroundColor(.secondary)
}
}
}
}
Dinamik List List(data:rowContent:) inicializatoridan yoki List tanasi ichidagi ForEach-dan foydalanadi. Birinchi variant har bir qator bitta ma'lumot elementiga mos kelganda qulay. Ikkinchisi — bo'limlar yoki ma'lumotlar o'rtasida qo'shimcha elementlar mavjud bo'lganda.
Identifikatsiya (Identifiable): Dinamik ro'yxatlar uchun ma'lumot elementlari Identifiable protokoliga mos kelishi kerak yoki data:id kortejida noyob identifikatorga KeyPath ko'rsatilishi kerak. SwiftUI o'zgarishlarni kuzatish uchun identifikatorlardan foydalanadi: qatorlarni qo'shish, o'chirish va ko'chirish.
Section — List-da qatorlarni sarlavha va ixtiyoriy footer bilan guruhlash uchun View. Section header va footer-ni ViewBuilder sifatida qabul qiladi, nafaqat matn, balki bo'lim sarlavhalari uchun maxsus View-lardan foydalanishga imkon beradi.
struct SettingsView: View {
var body: some View {
List {
Section(header: Text("Hisob")) {
Text("Ism")
Text("Elektron pochta")
}
Section(header: Text("Bildirishnomalar")) {
Toggle("Push", isOn: $pushEnabled)
Toggle("Email", isOn: $emailEnabled)
}
}
.listStyle(.insetGrouped)
}
}
// ForEach bilan dinamik bo'limlar
List {
ForEach(groupedData.keys.sorted(), id: \.self) { key in
Section(header: Text(key)) {
ForEach(groupedData[key]!) { item in
Text(item.title)
}
}
}
}
List stillari: SwiftUI .listStyle() modifikatori orqali bir nechta o'rnatilgan stillarni taqdim etadi. .insetGrouped — iOS Settings uchun standart, .plain — minimalist, .inset — chekinishlar bilan, .sidebar — iPad da Sidebar uchun.
SwiftUI Cookbook (2024) ga ko'ra, dinamik bo'limlar va ichida ForEach bo'lgan Section murakkab tuzilishdagi ilovalarda ma'lumotlarni guruhlash uchun standart naqshdir. Asosiy qoida: Section-ni Section ichiga joylashtirmang va List(data:) inicializatorini Section bilan birga ishlatmang — List tanasida ForEach dan foydalaning.
.swipeActions(edge:allowsFullSwipe:content:) — iOS 15+ uchun List qatorlariga surish harakatlarini qo'shadigan modifikator. Chapga (standart) yoki o'ngga surishda turli ranglar va rollar (destructive, cancel) bilan tugmalarni ko'rsatishga imkon beradi.
struct TaskList: View {
@Binding var tasks: [Task]
var body: some View {
List {
ForEach($tasks) { $task in
Text(task.title)
.swipeActions(edge: .trailing) {
Button("O'chirish", role: .destructive) {
tasks.removeAll { $0.id == task.id }
}
}
.swipeActions(edge: .leading) {
Button(task.isDone ? "Bekor qilish" : "Tayyor") {
task.isDone.toggle()
}
.tint(.green)
}
}
}
.refreshable {
// Asinxron ma'lumot yuklash
await loadTasks()
}
}
}
.refreshable — iOS 15+ uchun pull-to-refresh qo'shadigan modifikator. Foydalanuvchi ro'yxatni pastga tortganda bajariladigan asinxron closure (async) qabul qiladi. SwiftUI avtomatik ravishda yuklash indikatorini ko'rsatadi. Operatsiya tugagandan so'ng indikator yashiriladi.
.onDelete va .onMove — iOS 13+ uchun qatorlarni o'chirish va ko'chirishni qo'llab-quvvatlashni qo'shadigan modifikatorlar. Ulardan foydalanish uchun ma'lumotlarni ForEach bilan Binding-ga o'rang yoki List yoki ForEach da .onDelete(perform:) orqali closure-larni uzating.
List unumdorligi qatorlar soniga, har bir hujayraning murakkabligiga va ma'lumot yangilanishlarining chastotasiga bog'liq. SwiftUI lazy-loading va hujayralarni qayta ishlatishdan foydalanadi (UITableView.dequeueReusableCell ga o'xshash), lekin 500+ qatorli ro'yxatlar uchun qo'shimcha optimallashtirish talab qilinishi mumkin.
| Optimallashtirish | Tavsif | iOS versiyasi |
|---|---|---|
| Identifiable | Har bir element uchun noyob ID | iOS 13+ |
| EquatableView | Teng ma'lumotlarda qayta chizishni oldini oladi | iOS 13+ |
| id(_:) | ID o'zgarganda View-ni majburiy qayta yaratish | iOS 13+ |
| .equatable() | Equatable bo'yicha qat'iy taqqoslash | iOS 15+ |
| Diffable data | O'zgarishlarda avtomatik diff | iOS 15+ |
Muammo 1: tez-tez yangilanishlar. Ro'yxatdagi ma'lumotlar tez-tez yangilansa (masalan, har soniyada), List har bir holat o'zgarishida ko'rinadigan hujayralarni qayta chizishi mumkin. Yechim: ma'lumotlar uchun strukturalardan (value types) foydalaning — SwiftUI ularni qiymat bo'yicha taqqoslaydi va faqat o'zgargan qatorlarni qayta chizadi.
Muammo 2: og'ir hujayralar. Har bir qator murakkab View iyerarxiyasi, tasvirlar va animatsiyalarni o'z ichiga olsa, aylantirish sekinlashishi mumkin. Yechim: hujayralarni alohida View-larga ajrating, keraksiz qayta chizishlarning oldini olish uchun EquatableView dan foydalaning. SwiftUI Lab (2024) ga ko'ra, murakkab qatorni pastki komponentlarga bo'lish render vaqtini 30–50% ga kamaytiradi.
Muammo 3: ko'p sonli qatorlar. 1000+ qatorlarda List lazy-loading tufayli hali ham samarali ishlaydi, lekin layout hisoblash tufayli dastlabki yuklash sekinlashishi mumkin. Yechim: LazyVStack dan faqat List funksiyalari (surish, bo'limlar) kerak bo'lmagan bir xil turdagi qatorli ro'yxatlar uchun foydalaning. To'liq funksional ro'yxatlar uchun List eng yaxshi tanlov bo'lib qoladi.
Tez-tez beriladigan savollar
List — SwiftUI-da aylantiriladigan ma'lumotlar ro'yxatini ko'rsatish uchun konteyner View. Deklarativ API bilan UIKit-dagi UITableView ning analogi. Bo'limlar, surish harakatlari, pull-to-refresh, tahrirlash va .listStyle() orqali sozlashni qo'llab-quvvatlaydi.
List lazy-loading va hujayralarni qayta ishlatishdan foydalanadi — hujayralar aylantirish jarayonida yaratiladi. ScrollView + VStack barcha View-larni birdaniga yaratadi. 50+ qatorli ro'yxatlar uchun List afzal. Ruxsat etilgan kichik to'plamlar (20 elementgacha) uchun farq ahamiyatsiz.
.refreshable (iOS 15+) modifikatoridan foydalaning. Ma'lumot yangilash mantiqi bilan asinxron closure ni uzating. SwiftUI avtomatik ravishda yuklash indikatorini ko'rsatadi va asinxron operatsiya tugagandan so'ng uni yashiradi.
Header va ixtiyoriy footer bilan Section View-dan foydalaning. Section ichiga ro'yxat qatorlarini joylashtiring. Dinamik bo'limlar uchun groupedData bilan ForEach dan foydalaning. Ro'yxat stili iOS-ga o'xshash ko'rinish uchun .listStyle(.insetGrouped) orqali sozlanadi.
Ma'lumotlar uchun strukturalardan (value types) foydalaning, murakkab hujayralarni EquatableView bilan alohida View-larga ajrating, har bir qatorda tez-tez holat yangilanishlaridan qoching. 1000+ qatorli ro'yxatlar uchun List funksiyalari kerak bo'lmasa, LazyVStack ni ko'rib chiqing.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.