List — is een container-View in SwiftUI voor het weergeven van gegevens in een verticaal scrollbare lijst, een analogon van UITableView in UIKit. Volgens Apple Developer Documentation, 2024 ondersteunt List statische en dynamische secties, swipe-acties, het slepen van rijen en pull-to-refresh. In tegenstelling tot UITableView gebruikt List een declaratieve API op basis van SwiftUI en ForEach, waarbij automatisch het hergebruik van cellen en de prestaties bij een groot aantal rijen worden beheerd.
Belangrijkste punten
List — is een View dat een reeks elementen weergeeft in een verticaal scrollbare lijst. Het verscheen in iOS 13 samen met SwiftUI en is de primaire manier om gegevenslijsten weer te geven, ter vervanging van UITableView uit UIKit. List beheert automatisch het hergebruik van cellen, scrollen en prestaties.
List gebruikt lazy-loading: cellen worden gemaakt tijdens het scrollen, niet allemaal tegelijk. Dit onderscheidt het van VStack met ForEach in ScrollView, waar alle cellen worden gemaakt tijdens het renderen. List biedt ook ingebouwde ondersteuning voor swipe-acties, pull-to-refresh, bewerken (verwijderen/verplaatsen) en het selecteren van rijen.
Volgens Apple WWDC 2021 (Session 10072) kreeg List in iOS 15+ aanzienlijke prestatieverbeteringen dankzij een nieuw diffing-mechanisme op collectieniveau. Dit maakte List efficiënter bij het bijwerken van gegevens, vooral voor lijsten met honderden rijen.
Ontwikkelaars kiezen vaak tussen List en ScrollView met VStack voor het weergeven van een set Views. Het belangrijkste verschil: List gebruikt hergebruik van cellen (zoals UITableView), terwijl ScrollView + VStack alle Views tegelijk maakt. Voor lijsten met een vast aantal elementen (tot 20) is het verschil verwaarloosbaar. Voor dynamische lijsten met 50+ rijen heeft List de voorkeur vanwege de prestaties.
Statische List — is een lijst met een vast aantal rijen, rechtstreeks opgegeven in de body van de List. Wordt gebruikt voor menu's, instellingen en formulieren met een bekende set elementen. Elke rij wordt expliciet gedeclareerd, zonder lussen of ForEach.
// Statische lijst (voor menu's en instellingen)
List {
Text("Profiel")
Text("Instellingen")
Text("Over")
}
// Dynamische lijst (voor gegevens)
struct UserList: View {
let users: [User]
var body: some View {
List(users) { user in
HStack {
Text(user.name)
Text(user.role)
.foregroundColor(.secondary)
}
}
}
}
Dynamische List gebruikt de initialisator List(data:rowContent:) of ForEach in de body van de List. De eerste optie is handig wanneer elke rij overeenkomt met één gegevenselement. De tweede — wanneer er secties of extra elementen tussen gegevens zijn.
Identificatie (Identifiable): Voor dynamische lijsten moeten gegevenselementen voldoen aan het Identifiable-protocol of moet in de tuple data:id een KeyPath naar een unieke identificatie worden opgegeven. SwiftUI gebruikt identificaties om wijzigingen bij te houden: toevoegen, verwijderen en verplaatsen van rijen.
Section — is een View voor het groeperen van rijen in List met een kop en optionele footer. Section accepteert header en footer als ViewBuilder, waardoor niet alleen tekst maar ook aangepaste Views voor sectiekoppen kunnen worden gebruikt.
struct SettingsView: View {
var body: some View {
List {
Section(header: Text("Account")) {
Text("Naam")
Text("E-mail")
}
Section(header: Text("Meldingen")) {
Toggle("Push", isOn: $pushEnabled)
Toggle("Email", isOn: $emailEnabled)
}
}
.listStyle(.insetGrouped)
}
}
// Dynamische secties met ForEach
List {
ForEach(groupedData.keys.sorted(), id: \.self) { key in
Section(header: Text(key)) {
ForEach(groupedData[key]!) { item in
Text(item.title)
}
}
}
}
List-stijlen: SwiftUI biedt verschillende ingebouwde stijlen via de modifier .listStyle(). .insetGrouped — standaard voor iOS Settings, .plain — minimalistisch, .inset — met inspringingen, .sidebar — voor Sidebar op iPad.
Volgens SwiftUI Cookbook (2024) is Section met dynamische secties en ForEach erin een standaardpatroon voor het groeperen van gegevens in applicaties met een complexe structuur. Belangrijke regel: plaats geen Section in een Section en gebruik de initialisator List(data:) niet samen met Section — gebruik ForEach in de body van de List.
.swipeActions(edge:allowsFullSwipe:content:) — modifier voor iOS 15+ die swipe-acties toevoegt aan rijen van List. Maakt het mogelijk knoppen weer te geven bij het swipen naar links (standaard) of rechts, met verschillende kleuren en rollen (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("Verwijder", role: .destructive) {
tasks.removeAll { $0.id == task.id }
}
}
.swipeActions(edge: .leading) {
Button(task.isDone ? "Ongedaan maken" : "Gereed") {
task.isDone.toggle()
}
.tint(.green)
}
}
}
.refreshable {
// Asynchroon gegevens laden
await loadTasks()
}
}
}
.refreshable — modifier voor iOS 15+ die pull-to-refresh toevoegt. Accepteert een asynchrone closure (async) die wordt uitgevoerd wanneer de gebruiker de lijst omlaag trekt. SwiftUI toont automatisch de laadindicator. Nadat de bewerking is voltooid, wordt de indicator verborgen.
.onDelete en .onMove — modifiers voor iOS 13+ die ondersteuning bieden voor het verwijderen en verplaatsen van rijen. Om ze te gebruiken, wikkel de gegevens in ForEach met Binding of geef closures door via .onDelete(perform:) op List of ForEach.
List-prestaties zijn afhankelijk van het aantal rijen, de complexiteit van elke cel en de frequentie van gegevensupdates. SwiftUI gebruikt lazy-loading en hergebruik van cellen (vergelijkbaar met UITableView.dequeueReusableCell), maar aanvullende optimalisaties kunnen nodig zijn voor lijsten met 500+ rijen.
| Optimalisatie | Beschrijving | iOS-versie |
|---|---|---|
| Identifiable | Unieke ID voor elk element | iOS 13+ |
| EquatableView | Voorkomt opnieuw renderen bij gelijke gegevens | iOS 13+ |
| id(_:) | Geforceerd opnieuw aanmaken van View bij ID-wijziging | iOS 13+ |
| .equatable() | Strikte vergelijking op Equatable | iOS 15+ |
| Diffable data | Automatische diff bij wijzigingen | iOS 15+ |
Probleem 1: frequente updates. Als gegevens in de lijst vaak worden bijgewerkt (bijv. elke seconde), kan List zichtbare cellen opnieuw renderen bij elke statuswijziging. Oplossing: gebruik structuren (value types) voor gegevens — SwiftUI vergelijkt ze op waarde en rendert alleen gewijzigde rijen opnieuw.
Probleem 2: zware cellen. Als elke rij een complexe View-hiërarchie, afbeeldingen en animaties bevat, kan scrollen traag zijn. Oplossing: verplaats cellen naar afzonderlijke Views, gebruik EquatableView om onnodig opnieuw renderen te voorkomen. Volgens SwiftUI Lab (2024) vermindert het opsplitsen van een complexe rij in subcomponenten de rendertijd met 30–50%.
Probleem 3: groot aantal rijen. Bij 1000+ rijen werkt List nog steeds efficiënt dankzij lazy-loading, maar het initieel laden kan vertragen door het berekenen van de layout. Oplossing: gebruik LazyVStack alleen voor lijsten met homogene rijen waar List-functies (swipe, secties) niet nodig zijn. Voor volledig functionele lijsten blijft List de beste keuze.
Veelgestelde vragen
List — een container-View voor het weergeven van een scrollbare gegevenslijst in SwiftUI. Analoog aan UITableView in UIKit met een declaratieve API. Ondersteunt secties, swipe-acties, pull-to-refresh, bewerken en aanpassen via .listStyle().
List gebruikt lazy-loading en hergebruik van cellen — cellen worden gemaakt tijdens het scrollen. ScrollView + VStack maakt alle Views tegelijk. Voor lijsten met 50+ rijen heeft List de voorkeur. Voor vaste kleine sets (tot 20 elementen) is het verschil verwaarloosbaar.
Gebruik de modifier .refreshable (iOS 15+). Geef een asynchrone closure met de logica voor gegevensvernieuwing door. SwiftUI toont automatisch de laadindicator en verbergt deze na voltooiing van de asynchrone bewerking.
Gebruik Section View met een kop en optionele footer. Plaats de lijstrijen in de Section. Gebruik voor dynamische secties ForEach met groupedData. De lijststijl wordt geconfigureerd via .listStyle(.insetGrouped) voor een iOS-achtig uiterlijk.
Gebruik structuren (value types) voor gegevens, verplaats complexe cellen naar afzonderlijke Views met EquatableView, vermijd frequente statusupdates in elke rij. Overweeg voor lijsten met 1000+ rijen LazyVStack als List-functies niet nodig zijn.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook