List — egy konténer View a SwiftUI-ban adatok függőlegesen görgethető listában való megjelenítésére, az UIKit UITableView analógja. A Apple Developer Documentation, 2024 szerint a List támogatja a statikus és dinamikus szekciókat, csúsztatási műveleteket, sorok húzását és a pull-to-refresh-t. Az UITableView-tól eltérően a List deklaratív API-t használ SwiftUI és ForEach alapokon, automatikusan kezelve a cellák újrahasznosítását és a teljesítményt nagy számú sor esetén.
Főbb pontok
List — egy View, amely elemek sorozatát jeleníti meg egy függőlegesen görgethető listában. Az iOS 13-mal jelent meg a SwiftUI-val együtt, és ez az adatlisták megjelenítésének fő módja, felváltva az UIKit UITableView-jét. A List automatikusan kezeli a cellák újrahasznosítását, görgetést és teljesítményt.
A List lazy-loading-et használ: a cellák a görgetés során jönnek létre, nem egyszerre. Ez különbözteti meg a VStack-től ForEach-csel a ScrollView-on belül, ahol az összes cella a rendereléskor jön létre. A List beépített támogatást nyújt a csúsztatási műveletekhez, pull-to-refresh-hez, szerkesztéshez (törlés/áthelyezés) és sorok kiválasztásához.
A Apple WWDC 2021 (Session 10072) szerint a List iOS 15+-ban jelentős teljesítményjavulást kapott a kollekció szintű új diffing mechanizmusnak köszönhetően. Ez hatékonyabbá tette a List-et az adatok frissítésekor, különösen a több száz soros listák esetében.
A fejlesztők gyakran választanak a List és a ScrollView VStack-kel való használata között Views halmaz megjelenítéséhez. A kulcsfontosságú különbség: a List cella újrahasznosítást használ (mint az UITableView), míg a ScrollView + VStack az összes View-t egyszerre hozza létre. Rögzített számú elemű listákhoz (20-ig) a különbség elhanyagolható. Dinamikus, 50+ soros listákhoz a List előnyösebb a teljesítmény szempontjából.
Statikus List — rögzített számú sorral rendelkező lista, amelyek közvetlenül a List testében vannak megadva. Menük, beállítások és ismert elemkészletű űrlapok esetén használatos. Minden sor explicit módon, ciklusok vagy ForEach nélkül van deklarálva.
// Statikus lista (menühöz és beállításokhoz)
List {
Text("Profil")
Text("Beállítások")
Text("Névjegy")
}
// Dinamikus lista (adatokhoz)
struct UserList: View {
let users: [User]
var body: some View {
List(users) { user in
HStack {
Text(user.name)
Text(user.role)
.foregroundColor(.secondary)
}
}
}
}
Dinamikus List a List(data:rowContent:) inicializálót vagy a ForEach-et használja a List testén belül. Az első opció akkor kényelmes, ha minden sor egy adatelemnek felel meg. A második — amikor szekciók vagy további elemek vannak az adatok között.
Azonosítás (Identifiable): Dinamikus listákhoz az adatelemeknek meg kell felelniük az Identifiable protokollnak, vagy a data:id tuple-ben meg kell adni egy KeyPath-et egy egyedi azonosítóhoz. A SwiftUI azonosítókat használ a változások nyomon követéséhez: sorok hozzáadása, törlése és áthelyezése.
Section — egy View sorok List-ben való csoportosításához fejléccel és opcionális lábléccel. A Section header-t és footer-t ViewBuilder-ként fogadja el, lehetővé téve nemcsak szöveg, hanem egyedi Views használatát is a szekciófejlécekhez.
struct SettingsView: View {
var body: some View {
List {
Section(header: Text("Fiók")) {
Text("Név")
Text("E-mail")
}
Section(header: Text("Értesítések")) {
Toggle("Push", isOn: $pushEnabled)
Toggle("Email", isOn: $emailEnabled)
}
}
.listStyle(.insetGrouped)
}
}
// Dinamikus szekciók ForEach-csel
List {
ForEach(groupedData.keys.sorted(), id: \.self) { key in
Section(header: Text(key)) {
ForEach(groupedData[key]!) { item in
Text(item.title)
}
}
}
}
List stílusok: A SwiftUI több beépített stílust kínál a .listStyle() módosítón keresztül. .insetGrouped — szabványos az iOS Settings-hez, .plain — minimalista, .inset — behúzásokkal, .sidebar — Sidebar-hoz iPad-en.
A SwiftUI Cookbook (2024) szerint a Section dinamikus szekciókkal és ForEach-csel belül egy szabványos minta az adatok csoportosításához összetett szerkezetű alkalmazásokban. Kulcsszabály: ne ágyazz Section-t Section-be, és ne használd a List(data:) inicializálót Section-nel együtt — használj ForEach-et a List testében.
.swipeActions(edge:allowsFullSwipe:content:) — módosító iOS 15+ rendszerhez, amely csúsztatási műveleteket ad a List soraihoz. Lehetővé teszi gombok megjelenítését balra (alapértelmezett) vagy jobbra csúsztatáskor, különböző színekkel és szerepekkel (destructive, cancel).
struct TaskList: View {
@Binding var tasks: [Task]
var body: some View {
List {
ForEach($tasks) { $task in
Text(task.title)
.swipeActions(edge: .trailing) {
Button("Törlés", role: .destructive) {
tasks.removeAll { $0.id == task.id }
}
}
.swipeActions(edge: .leading) {
Button(task.isDone ? "Visszavonás" : "Kész") {
task.isDone.toggle()
}
.tint(.green)
}
}
}
.refreshable {
// Aszinkron adatbetöltés
await loadTasks()
}
}
}
.refreshable — módosító iOS 15+ rendszerhez, amely pull-to-refresh-t ad hozzá. Aszinkron closoure-t (async) fogad, amely akkor fut le, amikor a felhasználó lefelé húzza a listát. A SwiftUI automatikusan megjeleníti a betöltés jelzőt. A művelet befejezése után a jelző elrejtésre kerül.
.onDelete és .onMove — módosítók iOS 13+ rendszerhez, amelyek támogatást adnak a sorok törléséhez és áthelyezéséhez. Használatukhoz csomagold be az adatokat ForEach-be Binding-gel, vagy adj át closoure-öket a .onDelete(perform:) segítségével a List-en vagy ForEach-en.
A List teljesítménye függ a sorok számától, az egyes cellák összetettségétől és az adatfrissítések gyakoriságától. A SwiftUI lazy-loading-et és cella újrahasznosítást használ (hasonlóan az UITableView.dequeueReusableCell-hez), de további optimalizálásokra lehet szükség 500+ soros listák esetén.
| Optimalizálás | Leírás | iOS verzió |
|---|---|---|
| Identifiable | Egyedi ID minden elemhez | iOS 13+ |
| EquatableView | Elkerüli az újrarenderelést egyenlő adatoknál | iOS 13+ |
| id(_:) | View kényszerített újralétrehozása ID változásakor | iOS 13+ |
| .equatable() | Szigorú összehasonlítás Equatable alapján | iOS 15+ |
| Diffable data | Automatikus diff változásoknál | iOS 15+ |
1. probléma: gyakori frissítések. Ha a lista adatai gyakran frissülnek (pl. minden másodpercben), a List újrarenderelheti a látható cellákat minden állapotváltozáskor. Megoldás: használj struktúrákat (value types) az adatokhoz — a SwiftUI érték szerint hasonlítja össze őket, és csak a megváltozott sorokat rendereli újra.
2. probléma: nehéz cellák. Ha minden sor összetett View hierarchiát, képeket és animációkat tartalmaz, a görgetés lassú lehet. Megoldás: helyezd át a cellákat különálló Views-ekbe, használj EquatableView-t a felesleges újrarenderelések elkerüléséhez. A SwiftUI Lab (2024) szerint egy összetett sor alkomponensekre bontása 30–50%-kal csökkenti a renderelési időt.
3. probléma: nagy számú sor. 1000+ sor esetén a List továbbra is hatékonyan működik a lazy-loading-nek köszönhetően, de a kezdeti betöltés lelassulhat a layout számítás miatt. Megoldás: használj LazyVStack-et csak homogén sorokból álló listákhoz, ahol nincs szükség a List funkcióira (csúsztatás, szekciók). Teljesen funkcionális listákhoz a List továbbra is a legjobb választás.
Gyakran Ismételt Kérdések
List — konténer View görgethető adatlista megjelenítéséhez a SwiftUI-ban. Az UITableView analógja az UIKit-ban deklaratív API-val. Támogatja a szekciókat, csúsztatási műveleteket, pull-to-refresh-t, szerkesztést és testreszabást a .listStyle()-on keresztül.
A List lazy-loading-et és cella újrahasznosítást használ — a cellák a görgetés során jönnek létre. A ScrollView + VStack az összes View-t egyszerre hozza létre. 50+ soros listákhoz a List előnyösebb. Rögzített kis halmazokhoz (20 elemig) a különbség elhanyagolható.
Használd a .refreshable (iOS 15+) módosítót. Adj át egy aszinkron closoure-t az adatfrissítési logikával. A SwiftUI automatikusan megjeleníti a betöltés jelzőt, és elrejti azt az aszinkron művelet befejezése után.
Használd a Section View-t fejléccel és opcionális lábléccel. Helyezd a lista sorait a Section-be. Dinamikus szekciókhoz használj ForEach-et groupedData-val. A lista stílusa a .listStyle(.insetGrouped) segítségével állítható be iOS-szerű megjelenéshez.
Használj struktúrákat (value types) az adatokhoz, helyezd át az összetett cellákat külön Views-ekbe EquatableView-val, kerüld a gyakori állapotfrissítéseket minden sorban. 1000+ soros listákhoz fontold meg a LazyVStack-et, ha nincs szükség a List funkcióira.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is