Technologische Neuigkeiten, Bewertungen und Tipps!

Arbeiten mit Liste in SwiftUI

Hinweis: Der folgende Artikel hilft Ihnen weiter: Arbeiten mit Liste in SwiftUI

Zurück zum Blog

Eine Listenansicht in SwiftUI zeigt Zeilen in einer vertikalen, einzelnen Spalte. Es handelt sich um eine scrollbare Liste von Daten, mit denen Sie interagieren können. In diesem Tutorial besprechen wir, wie Sie mit SwiftUI eine Listenansicht erstellen und anpassen können.

Hier erfahren Sie, worauf wir eingehen:

  • So verwenden Sie List und ForEach zum Erstellen dynamischer listenbasierter Benutzeroberflächen
  • Wichtige Aspekte von List, wie Identifiable und seine Datenquelle
  • Verwenden Sie List in Verbindung mit ForEach, um bessere Listen zu erstellen
  • Entfernen von Objekten aus einer Liste mit ForEach und onDelete()
  • Erstellen einer unterteilten Liste mit verschachtelten ForEach- und Section-Listen

Werfen wir einen Blick auf die Listenansicht in SwiftUI. Die grundlegendste Einrichtung einer Liste ist eigentlich ziemlich einfach.

List(movies, id: \.id) { movie in
Text(Film.Titel)
}

Bedenken Sie, dass wir über ein Array von Movie-Objekten verfügen, jedes mit einer ID und einem Titel. Mit dem obigen Code können Sie eine Listenansicht mit Textelementen für jeden Film im Array anzeigen.

Im obigen Code arbeiten wir mit einem Array von Movie-Objekten. Hier ist der Code für die Movie-Struktur:

Strukturfilm: Identifizierbar {
var id = UUID()
Var-Titel:String
}
Die Movie-Struktur entspricht dem Identifiable-Protokoll. Jeder Typ, der das Identifiable-Protokoll verwendet, muss über eine ID-Eigenschaft verfügen, die eine „stabile“ Identität für das Objekt bereitstellt. Im Wesentlichen bedeutet dies, dass die ID-Eigenschaft für jedes Objekt eindeutig sein muss. Wir verwenden dafür eine UUID, Sie könnten aber beispielsweise auch einen ganzzahligen Indexschlüssel aus einer Datenbank verwenden.

Dies ist das Array von Filmobjekten, auf dem die Listenansicht basiert:

@State var movies = [
Movie(title: “Episode IV – A New Hope”),
Movie(title: “Episode V – The Empire Strikes Back”),
Movie(title: “Episode VI – Return of the Jedi”),

]
Schauen wir uns den Code, den wir zuvor für die Listenansicht verwendet haben, genauer an:

List(movies, id: \.id) { movie in
Text(Film.Titel)
}

Der Listenansicht-Initialisierer verfügt über drei Parameter:

  1. Unbenannte Parameterdaten, also die Daten, die wir in der Listenansicht anzeigen möchten. In unserem Beispiel handelt es sich bei diesen Daten um das Movies-Array.
  2. Ein Schlüsselpfad für den ID-Parameter, der die Movie-Eigenschaft angibt, die wir zur eindeutigen Identifizierung von Objekten im Movies-Array verwenden möchten. (Der Parameter „id“ ist hier überflüssig. Sie können entweder „id“ oder „Identifiable“ oder beides verwenden.)
  3. Ein Abschluss für den rowContent-Parameter; den Inhalt einzelner Listenzeilen. Da es sich um den letzten Parameter handelt, können wir die Syntax für den nachgestellten Abschluss verwenden.

Der letzte Parameter ist der interessanteste. Es ist der Abschluss, der den Inhalt für jede Zeile in der Liste bereitstellt. Ähnlich wie map(_:) wird es für jedes Element in Filmen aufgerufen und sollte eine anzuzeigende Ansicht zurückgeben. Im obigen Code geben wir einfach eine Textansicht zurück. Wir nutzen auch das bereitgestellte Filmobjekt.

Wenn Sie den Schritten in diesem Tutorial folgen möchten, können Sie ein neues Xcode-Projekt erstellen. Wählen Sie die App-Vorlage, SwiftUI für die Schnittstelle und SwiftUI-App für den Lebenszyklus. Sie können in der Standardansicht ContentView arbeiten oder Ihre eigene erstellen. Vergessen Sie nicht, es in der App-Struktur zu aktualisieren!

Die Listenansicht ist im Wesentlichen ein Container für Unteransichten, die gescrollt werden können. Es ähnelt Ansichten wie VStack und HStack sowie UITableViewController für Storyboard-basierte Apps.

Sie können tatsächlich eine einfache alte statische Listenansicht aus einigen Unteransichten erstellen:

Aufführen {
Text („Die Gefährten“)
Text („Die zwei Türme“)
Text („Die Rückkehr des Königs“)
}

Das Besondere an List ist, dass es mithilfe einer Datenquelle und etwas Code, der Unteransichten für einzelne Elemente bereitstellt, dynamisch Unteransichten erstellen kann. Und in SwiftUI können Sie List mit ForEach kombinieren, um noch mehr zu erreichen.

Hier ist ein Beispiel:

Aufführen {
ForEach(movies, id: \.id) { movie in
Text(Film.Titel)
}
}

Im obigen Code haben wir die vorherigen Parameter für List getrennt und der ForEach-Struktur hinzugefügt.

Die ForEach-Struktur berechnet Aufrufe bei Bedarf aus der Filmsammlung, ähnlich wie List das gemacht hat. Diese Ansichten sind Unteransichten von List, was bedeutet, dass Sie das gleiche Ergebnis erhalten, als würden Sie nur List verwenden.

Welchen Vorteil bietet die Verwendung von ForEach? Zunächst einmal funktioniert ForEach eher wie ein Generator oder Datenanbieter als wie eine Ansicht. Durch die Verwendung von ForEach erhalten Sie auch Zugriff auf Datenaktionen wie onDelete(), onInsert() und onMove(), was List nicht kann.

Die ForEach-Struktur kann mit jeder Art von Ansicht verwendet werden, die mehrere Unteransichten enthalten kann, z. B. Stapel. Hier ist ein Beispiel:

HStack {
Für jede([“File”, “Edit”, “View”]id: \.hash) { Titel in
Text(Titel)
}
}

Sie können ForEach auch mit onDelete() verwenden, um Elemente aus der der Liste zugrunde liegenden Datenquelle zu entfernen. Hier ist ein Beispiel:

Aufführen {
ForEach(movies, id: \.id) { movie in
Text(Film.Titel)
}
.onDelete { indexSet in
für Index in indexSet {
movies.remove(at: index)
}
}
}

Der Modifikator onDelete() wird aufgerufen, wenn Sie ein Listenelement nach rechts wischen, so wie Sie es tun würden, um ein Element unter iOS zu löschen. Es handelt sich um einen Vorteil, der auch in der allgegenwärtigen Tabellenansicht integriert ist, und natürlich hat List ihn auch.

Damit dies funktioniert, müssen Sie die Datenquelle jedoch als Status markieren. In unserem Beispiel bedeutet das, dass wir den Eigenschafts-Wrapper @State zur Eigenschaft movies hinzufügen müssen.

@State var movies =

Die Ansicht hängt jetzt vom Status der Filme ab. Das bedeutet, dass die Ansicht jetzt auch aktualisiert wird, wenn Sie ein Element aus dem Filmarray entfernen.

Sie müssen die Ansicht für die Listenzeilen innerhalb der Liste nicht codieren. Sie können sie auch in eine separate Ansicht abstrahieren und in der Liste auf die Ansicht verweisen. Etwas wie List() { MovieRow() }.

Wenn List nur eine Reihe von Zeilen in einer Liste anzeigt und ForEach Ansichten basierend auf einer Datenquelle generiert, bedeutet das, dass wir beide verwenden können, um unterteilte Listen zu erstellen. Finden wir heraus wie!

Zunächst nehmen wir einige Änderungen an den Movie-Objekten vor. So was:

Strukturfilm: Identifizierbar {
var id = UUID()
Var-Titel:String
var period:Periode
}

Die Movie-Struktur verfügt jetzt über eine Eigenschaft period, die wir zum Erstellen einer unterteilten Liste verwenden. Jede Filmperiode erhält einen eigenen Listenabschnitt.

Hier ist die Periodenaufzählung:

Aufzählungszeitraum: String, CaseIterable {
Fall Original = „Originaltrilogie“
case prequel = „Prequel-Trilogie“
case sequel = „Fortsetzung der Trilogie“
case standalone = „Standalone“
}

Die Aufzählung verwendet Rohwerte, sodass wir sie als Periodentyp und als String-Werte verwenden können. Mit dem CaseIterable-Protokoll können wir die Aufzählung über die Eigenschaft allCases als Array iterieren.

Als nächstes brauchen wir natürlich ein paar Filme!

var movies = [
Movie(title: “Episode IV – A New Hope”, period: .original),
Movie(title: “Episode V – The Empire Strikes Back”, period: .original),
Movie(title: “Episode VI – Return of the Jedi”, period: .original),

Movie(title: “Star Wars: The Clone Wars”, period: .standalone),
Movie(title: “Rogue One”, period: .standalone),
Movie(title: “Solo”, period: .standalone),
Movie(title: “The Mandalorian”, period: .standalone)
]

Okay, jetzt zu dieser unterteilten Liste. Hier ist der Code, den wir verwenden:

Aufführen {
ForEach(Period.allCases, id: \.rawValue) { period in
Section(header: Text(period.rawValue)) {
ForEach(movies.filter { $0.period == period }) { movie in
VStack {
Text(Film.Titel)
Text(movie.period.rawValue)
}
}
}
}
}

Wie funktioniert das?

  • Aus der Vogelperspektive können Sie sehen, dass wir eine Liste mit zwei verschachtelten ForEach-Strukturen erstellt haben. Wir durchlaufen zunächst die Abschnitte und durchlaufen für jeden Abschnitt die darin enthaltenen Filme.
  • Die ForEach-Struktur für Period.allCases durchläuft alle Fälle von Period. Sie werden durch ihren Rohwert, also durch ihre Zeichenfolge, eindeutig identifiziert. (Aus Mangel an einer besseren Alternative; dies funktioniert nicht für doppelte Zeichenfolgen!)
  • Die Abschnittsansicht bietet eine Gruppierung aus einer Kopfzeile und mehreren Zeilen. Wie Sie sehen, verwenden wir eine Textansicht, die den Punkt als Kopfzeile enthält. Beachten Sie, dass diese Header für jeden Fall der Period-Enumeration erstellt werden.
  • In jedem Abschnitt erstellen wir eine weitere ForEach-Struktur. Dabei wird movies.filter { } als Datenquelle verwendet, die die Elemente aus Filmen zurückgibt, deren Zeitraum mit dem Zeitraum des Abschnitts übereinstimmt.
  • Schließlich erstellen wir auf der innersten Ebene zwei einfache Textansichten, um den Namen des Films und den Zeitraum, zu dem er gehört, anzuzeigen. Sauber!

An dieser Stelle ist es klug, sich daran zu erinnern, dass SwiftUI eine deklarative Sprache zum Erstellen von Benutzeroberflächen ist. Wir beschreiben eigentlich nur die Hierarchie und Struktur der Benutzeroberfläche, die wir wollen, und auf welchen Daten SwiftUI die Benutzeroberfläche basieren sollte. SwiftUI kümmert sich um den Rest.

Auch wenn wir dynamische Konstrukte wie ForEach verwenden, sind die Ansichten fest und statisch, bis sich die Daten ändern. Wir hätten all diese Filme, Abschnitte und Stapel genauso gut in einer großen Codehierarchie zusammenfassen können. Das ForEach ist für uns als Programmierer da, damit wir weniger programmieren und mehr bauen können. Eindrucksvoll!

In diesem Tutorial haben wir besprochen, wie List funktioniert und wie Sie damit zeilen-/spaltenähnliche Layouts in SwiftUI erstellen können. Folgendes haben Sie gelernt:

  • Wie Sie List zum Erstellen von Benutzeroberflächen verwenden können
  • Warum die Objekte der Datenquelle einer Liste identifizierbar sein müssen
  • Verwenden von List zusammen mit ForEach
  • So entfernen Sie Objekte aus der Liste und antworten mit @State
  • Erstellen einer unterteilten Liste mit verschachteltem ForEach

Table of Contents