List — SwiftUI-də məlumatları şaquli olaraq sürüşdürülən siyahı şəklində göstərmək üçün konteyner View-dir, UIKit-də UITableView-un analoqudur. Apple Developer Documentation, 2024-ə görə, List statik və dinamik bölmələri, sürüşdürmə hərəkətlərini, sətirlərin sürüklənməsini və pull-to-refresh-i dəstəkləyir. UITableView-dən fərqli olaraq, List SwiftUI və ForEach-ə əsaslanan deklarativ API-dən istifadə edir, hüceyrələrin təkrar istifadəsini və çox sayda sətir olduqda performansı avtomatik idarə edir.
Əsas məqamlar
List — elementlər ardıcıllığını şaquli sürüşdürülən siyahıda göstərən View-dir. iOS 13 ilə birlikdə SwiftUI-də ortaya çıxdı və UIKit-dən UITableView-i əvəz edərək məlumat siyahılarını göstərməyin əsas yoludur. List hüceyrələrin təkrar istifadəsini, sürüşdürməni və performansı avtomatik idarə edir.
List lazy-loading istifadə edir: hüceyrələr sürüşdürdükcə yaradılır, hamısı bir anda deyil. Bu onu ScrollView daxilində VStack ilə ForEach-dən fərqləndirir, burada bütün hüceyrələr render zamanı yaradılır. List həmçinin sürüşdürmə hərəkətləri, pull-to-refresh, redaktə (sil/move) və sətir seçimi üçün daxili dəstək təmin edir.
Apple WWDC 2021 (Session 10072)-yə görə, iOS 15+-də List kolleksiya səviyyəsində yeni diffing mexanizmi sayəsində əhəmiyyətli performans təkmilləşdirmələri əldə etdi. Bu, List-i məlumatları yeniləyərkən daha səmərəli etdi, xüsusən də yüzlərlə sətir olan siyahılar üçün.
Tərtibatçılar tez-tez View dəstini göstərmək üçün List ilə ScrollView + VStack arasında seçim edirlər. Əsas fərq: List hüceyrələrin təkrar istifadəsindən istifadə edir (UITableView kimi), ScrollView + VStack isə bütün View-ləri bir anda yaradır. Sabit sayda element olan siyahılar üçün (20-yə qədər) fərq cüzidir. 50+ sətir olan dinamik siyahılar üçün List performans baxımından daha üstündür.
Statik List — birbaşa List-in gövdəsində müəyyən edilmiş sabit sayda sətir olan siyahıdır. Məlum element dəsti olan menyular, parametrlər və formalar üçün istifadə olunur. Hər sətir dövr və ya ForEach olmadan açıq şəkildə elan edilir.
// Statik siyahı (menyu və parametrlər üçün)
List {
Text("Profil")
Text("Parametrlər")
Text("Haqqında")
}
// Dinamik siyahı (məlumatlar üçün)
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:) inicallaşdırıcısından və ya List-in gövdəsi daxilində ForEach-dən istifadə edir. Birinci seçim hər sətir bir məlumat elementinə uyğun olduqda rahatdır. İkincisi — bölmələr və ya məlumatlar arasında əlavə elementlər olduqda.
İdentifikasiya (Identifiable): Dinamik siyahılar üçün məlumat elementləri Identifiable protokoluna uyğun olmalı və ya data:id kortejində unikal identifikatora KeyPath göstərilməlidir. SwiftUI dəyişiklikləri izləmək üçün identifikatorlardan istifadə edir: sətirlərin əlavə edilməsi, silinməsi və yerdəyişməsi.
Section — başlıq və isteğe bağlı footer ilə List-də sətirləri qruplaşdırmaq üçün View-dir. Section header və footer-i ViewBuilder kimi qəbul edir, yalnız mətn deyil, həm də bölmə başlıqları üçün fərdi View-lərdən istifadə etməyə imkan verir.
struct SettingsView: View {
var body: some View {
List {
Section(header: Text("Hesab")) {
Text("Ad")
Text("E-poçt")
}
Section(header: Text("Bildirişlər")) {
Toggle("Push", isOn: $pushEnabled)
Toggle("Email", isOn: $emailEnabled)
}
}
.listStyle(.insetGrouped)
}
}
// ForEach ilə dinamik bölmələr
List {
ForEach(groupedData.keys.sorted(), id: \.self) { key in
Section(header: Text(key)) {
ForEach(groupedData[key]!) { item in
Text(item.title)
}
}
}
}
List stilləri: SwiftUI .listStyle() modificatoru vasitəsilə bir neçə daxili stil təqdim edir. .insetGrouped — iOS Settings üçün standart, .plain — minimalist, .inset — abzaslarla, .sidebar — iPad-də Sidebar üçün.
SwiftUI Cookbook (2024)-ə görə, dinamik bölmələr və daxilində ForEach olan Section mürəkkəb quruluşlu tətbiqlərdə məlumatların qruplaşdırılması üçün standart nümunədir. Əsas qayda: Section-u Section-un içərisinə yerləşdirməyin və List(data:) inicallaşdırıcısını Section ilə birlikdə istifadə etməyin — List-in gövdəsində ForEach istifadə edin.
.swipeActions(edge:allowsFullSwipe:content:) — iOS 15+ üçün List sətirlərinə sürüşdürmə hərəkətləri əlavə edən modificator. Sola (defolt) və ya sağa sürüşdürdükdə müxtəlif rənglər və rollarla (destructive, cancel) düymələri göstərməyə imkan verir.
struct TaskList: View {
@Binding var tasks: [Task]
var body: some View {
List {
ForEach($tasks) { $task in
Text(task.title)
.swipeActions(edge: .trailing) {
Button("Sil", role: .destructive) {
tasks.removeAll { $0.id == task.id }
}
}
.swipeActions(edge: .leading) {
Button(task.isDone ? "Geri al" : "Hazırdır") {
task.isDone.toggle()
}
.tint(.green)
}
}
}
.refreshable {
// Asinxron məlumat yükləmə
await loadTasks()
}
}
}
.refreshable — iOS 15+ üçün pull-to-refresh əlavə edən modificator. İstifadəçi siyahını aşağı çəkdikdə yerinə yetirilən asinxron closure (async) qəbul edir. SwiftUI avtomatik olaraq yükləmə göstəricisini göstərir. Əməliyyat başa çatdıqdan sonra göstərici gizlədilir.
.onDelete və .onMove — iOS 13+ üçün sətirlərin silinməsi və yerdəyişməsi dəstəyi əlavə edən modificatorlar. Onlardan istifadə etmək üçün məlumatları ForEach ilə Binding-ə sarın və ya .onDelete(perform:) vasitəsilə List və ya ForEach-ə closure-ları ötürün.
List performansı sətirlərin sayından, hər hüceyrənin mürəkkəbliyindən və məlumat yeniləmələrinin tezliyindən asılıdır. SwiftUI lazy-loading və hüceyrələrin təkrar istifadəsindən istifadə edir (UITableView.dequeueReusableCell-ə bənzər), lakin 500+ sətirli siyahılar üçün əlavə optimallaşdırmalar tələb oluna bilər.
| Optimallaşdırma | Təsvir | iOS versiyası |
|---|---|---|
| Identifiable | Hər element üçün unikal ID | iOS 13+ |
| EquatableView | Bərabər məlumatlarda yenidən çəkmənin qarşısını alır | iOS 13+ |
| id(_:) | ID dəyişdikdə View-in məcburi yenidən yaradılması | iOS 13+ |
| .equatable() | Equatable-ə əsasən ciddi müqayisə | iOS 15+ |
| Diffable data | Dəyişikliklərdə avtomatik diff | iOS 15+ |
Problem 1: tez-tez yeniləmələr. Siyahıdakı məlumatlar tez-tez yenilənirsə (məsələn, hər saniyə), List hər vəziyyət dəyişikliyində görünən hüceyrələri yenidən çəkə bilər. Həll: məlumatlar üçün strukturlardan (value types) istifadə edin — SwiftUI onları dəyərə görə müqayisə edir və yalnız dəyişmiş sətirləri yenidən çəkir.
Problem 2: ağır hüceyrələr. Hər sətir mürəkkəb View iyerarxiyası, şəkillər və animasiyalar ehtiva edərsə, sürüşdürmə yavaşlaya bilər. Həll: hüceyrələri ayrı View-lərə ayırın, artıq yenidən çəkmələrin qarşısını almaq üçün EquatableView istifadə edin. SwiftUI Lab (2024)-ə görə, mürəkkəb sətirin alt komponentlərə bölünməsi render vaxtını 30–50% azaldır.
Problem 3: çox sayda sətir. 1000+ sətir olduqda List lazy-loading sayəsində hələ də səmərəli işləyir, lakin layout hesablanması səbəbindən ilkin yükləmə yavaşlaya bilər. Həll: LazyVStack-dən yalnız List funksiyaları (sürüşdürmə, bölmələr) lazım olmayan eynitip sətirləri olan siyahılar üçün istifadə edin. Tam funksional siyahılar üçün List ən yaxşı seçim olaraq qalır.
Tez-tez verilən suallar
List — SwiftUI-də sürüşdürülən məlumat siyahısını göstərmək üçün konteyner View. Deklarativ API ilə UIKit-də UITableView-un analoqu. Bölmələri, sürüşdürmə hərəkətlərini, pull-to-refresh-i, redaktəni və .listStyle() vasitəsilə fərdiləşdirməni dəstəkləyir.
List lazy-loading və hüceyrələrin təkrar istifadəsindən istifadə edir — hüceyrələr sürüşdürdükcə yaradılır. ScrollView + VStack bütün View-ləri bir anda yaradır. 50+ sətirli siyahılar üçün List daha üstündür. Sabit kiçik dəstlər üçün (20 elementə qədər) fərq cüzidir.
.refreshable (iOS 15+) modificatorundan istifadə edin. Məlumat yeniləmə məntiqi ilə asinxron closure ötürün. SwiftUI avtomatik olaraq yükləmə göstəricisini göstərir və asinxron əməliyyat başa çatdıqdan sonra onu gizlədir.
Header və isteğe bağlı footer ilə Section View-dən istifadə edin. Section-un daxilinə siyahı sətirlərini yerləşdirin. Dinamik bölmələr üçün groupedData ilə ForEach istifadə edin. Siyahı stili iOS-a bənzər görünüş üçün .listStyle(.insetGrouped) vasitəsilə konfiqurasiya edilir.
Məlumatlar üçün strukturlardan (value types) istifadə edin, mürəkkəb hüceyrələri EquatableView ilə ayrı View-lərə ayırın, hər sətirdə tez-tez vəziyyət yeniləmələrindən qaçın. 1000+ sətirli siyahılar üçün List funksiyaları lazım deyilsə, LazyVStack-i nəzərdən keçirin.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun