UITableView im Griff – Teil 1

Einfache Table-View erstellen

Die Klasse UITableView gehört zweifelsohne zu den wohl am häufigsten eingesetzten UI-Elementen in der iOS- und tvOS-Entwicklung. Mit ihr lassen sich Listenansichten umsetzen, durch die Nutzer vertikal scrollen können. Jedes Element innerhalb einer solchen Liste entspricht einer Zelle, abgebildet durch Instanzen der Klasse UITableViewCell.

In dieser Artikelreihe möchte ich euch den Einsatz der Klasse UITableView Schritt für Schritt vorstellen und euch zeigen, wie ihr effektiv und effizient mit ihr arbeiten könnt. Los geht es hierbei mit den Basics und der grundlegenden Erstellung einer Liste auf Basis von UITableView.

Table-View im Storyboard hinzufügen

Generell führt der wohl einfachste und komfortabelste Weg zum Erstellen einer Table-View über ein Storyboard. In der Object Library findet ihr ein entsprechendes UI-Element, das ihr einem bestehenden View-Controller hinzufügen könnt. Für einen ersten Test bietet es sich an, die Table-View der Größe des View-Controllers anzupassen.

In der Object Library findet ihr eine Vorlage zum Hinzufügen einer Table-View.
In der Object Library findet ihr eine Vorlage zum Hinzufügen einer Table-View.
Viele Table-Views nutzen die gesamte verfügbare Fläche des zugrundeliegenden View-Controllers.
Viele Table-Views nutzen die gesamte verfügbare Fläche des zugrundeliegenden View-Controllers.

Zellen-Vorlage erstellen

Wie geschrieben zeigt eine Table-View für jede Zelle eine Instanz der Klasse UITableViewCell an. Um die so effizient wie möglich zu nutzen, erstellt man in der Regel zunächst Vorlagen auf Basis von UITableViewCell, die dem gewünschten Aussehen für die Zellen einer Table-View entsprechen. Viele Table-Views besitzen nur eine einzige solche Vorlage, und das ist auch vollkommen in Ordnung.

Diese Vorlage definiert, wie Zellen aussehen und welche Inhalte sie besitzen. Der einfachste Weg zum Erstellen einer solchen Vorlage führt erneut über das Storyboard. Man wählt dazu zunächst die Table-View aus und wechselt in den Attributes Inspector. Im obersten Abschnitt Table View wählt man unter Content als Erstes Dynamic Prototypes aus (was dem Standard entspricht und somit bereits geschehen sein sollte) und setzt im Anschluss im Feld Prototype Cells den Wert 1. Der Table-View wird so eine erste Zellen-Vorlage hinzugefügt.

Der Table-View wurde eine Vorlage für eine Zelle hinzugefügt.
Der Table-View wurde eine Vorlage für eine Zelle hinzugefügt.

Um diese Vorlage anzupassen, wählt man sie im Storyboard aus. Hierbei kann die Document Outline Area sehr hilfreich sein, dort findet sich die Zelle als erstes Element unterhalb der Table-View.

Für den Anfang nehmen wir hier keine großartigen Anpassungen vor, stattdessen sollen die Zellen der Table-View einfach nur ein simples Label anzeigen. Um das zu erreichen, wählt man die Table-View-Cell im Storyboard aus und setzt im Attributes Inspector unter Style den Wert Basic. Innerhalb des Storyboards wird die Zelle im Anschluss direkt aktualisiert und zeigt den statischen Text Title an. Der wird zur Laufzeit von uns durch andere Inhalte ersetzt.

Wie geschrieben ist eine Table-View-Cell typischerweise eine Vorlage und enthält keine konkreten Informationen. Sie bestimmt nur, wie eine für unsere App benötigte Zelle aussieht.

Um die Konfiguration der Table-View-Cell abzuschließen, müssen wir ihr noch einen passenden Identifier geben. Damit identifizieren wir diese Zellen-Vorlage im Code und können sie entsprechend laden (dazu gleich mehr). Den Identifier setzt man über das gleichnamige Textfeld im Attributes Inspector, nachdem man die Table-View-Cell ausgewählt hat. Als Beispiel lässt sich hier an dieser Stelle der Bezeichner BasicCell eintragen.

Die Zellen-Vorlage wurde von uns auf die gewünschte Art und Weise konfiguriert.
Die Zellen-Vorlage wurde von uns auf die gewünschte Art und Weise konfiguriert.

Damit ist der erste Schritt getan und wir verfügen nun über einen View-Controller, der eine Table-View lädt und anzeigt und eine Vorlage für die anzuzeigenden Zellen definiert. Jetzt geht es darum, diese Table-View mit passenden Inhalten zu füllen.

Delegation mittels UITableViewDataSource

Die Inhalte einer Table-View speisen sich aus einem Protokoll namens UITableViewDataSource. Die Table-View, die wir eben im Storyboard hinzugefügt haben, benötigt einen passenden Delegate, der zu diesem Protokoll konform ist. In vielen Fällen dient der zugrundeliegende View-Controller als solcher Delegate.

Der komfortabelste Weg, den View-Controller als Delegate der Table-View zu definieren, führt erneut über das Storyboard. Dazu führt man einen Sekundärklick auf der Table-View aus und zieht dann bei Halten des Klicks eine Verbindung zum View-Controller. In dem erscheinenden Popup, das bei Beenden des Klicks erscheint, wählt man den Punkt dataSource aus.

Durch die Verbindung von Table-View und View-Controller kann letzter als Data Source für die Table-View bequem über das Storyboard definiert werden.
Durch die Verbindung von Table-View und View-Controller kann letzter als Data Source für die Table-View bequem über das Storyboard definiert werden.

Damit sind alle Arbeiten innerhalb des Storyboards abgeschlossen. Als Nächstes wechseln wir in den Code des zugrundeliegenden View-Controllers. Da der als Data Source für die Table-View fungiert, muss er konform zum genannten UITableViewDataSource-Protokoll sein.

Die zwei wichtigsten (und auch zwingend zu implementierenden) Methoden des UITableViewDataSource-Protokolls sind die folgenden:

  • tableView(_:numberOfRowsInSection:): Gibt die Anzahl der Zellen innerhalb einer Section an.
  • tableView(_:cellForRowAt:) Gibt die Zelle für eine spezifische Position innerhalb der Table-View zurück.

Sections brauchen uns für den Moment noch nicht zu interessieren. Kurz gesagt dienen sie dazu, eine Table-View in mehrere logische Bereiche zu untergliedern, von denen jeder eine beliebige Anzahl an Zellen enthalten kann. Jede Table-View besitzt standardmäßig immer genau eine solche Section.

Die erstgenannte Methode tableView(_:numberOfRowsInSection:) liefert uns als Parameter einerseits die Table-View, für die die Anzahl der Zellen zurückgegeben werden soll als auch die Section, für die die Anzahl der Zellen benötigt wird. Da die Sections uns wie geschrieben momentan noch nicht interessieren, geben wir innerhalb der Methode beispielsweise schlicht 10 zurück, um so zum Ausdruck zu bringen, dass wir zehn Zellen in der Table-View anzeigen möchten.

Etwas komplexer wird es in der zweiten Methode tableView(_:cellForRowAt:). Die liefert uns neben der Table-View einen Index-Path, der die Position der Zelle enthält, die über diese Methode zurückgegeben werden soll.

Man muss sich das ganze wie folgt vorstellen: Wird die Table-View geladen, prüft sie zunächst, wie viele Zellen (auf Basis der Methode tableView(_:numberOfRowsInSection:)) angezeigt werden sollen. Für jede dieser Zellen ruft die Table-View im Anschluss die Methode tableView(_:cellForRowAt:) auf und übergibt hierbei die aktuelle Position. Zunächst möchte sie die erste anzuzeigende Zelle erhalten, dann die zweite, dann die dritte und so weiter.

Innerhalb dieser Methode erstellen wir die UITableViewCell-Instanz, die unserer gewünschten Vorlage entspricht, und konfigurieren sie. Um eine passende Instanz zu laden nutzen wir die Methode dequeueReusableCell(withIdentifier:for:), die wir auf der übergebenen UITableView-Instanz aufrufen können. Der übergeben wir zum einen den Identifier der gewünschten Zelle (in diesem Beispiel BasicCell) und die Position in Form des Index-Path; letzteren erhalten wir als Parameter durch die Delegate-Methode selbst.

Die so erhaltene UITableViewCell-Instanz wird im nächsten Schritt konfiguriert. Dazu greifen wir auf deren textLabel-Property zu und setzen einen dynamischen Text, der die Position der aktuellen Zelle ausgibt. Hierfür nutzen wir den Index-Path und dessen Property row, die eben genau jene Information enthält. Die so erstellte und konfigurierte Zelle geben wir im Anschluss mittels return zurück. Das vollständige Listing hierzu seht ihr im Folgenden:

class ViewController: UIViewController, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "BasicCell", for: indexPath)
        cell.textLabel?.text = "Zelle \(indexPath.row)"
        return cell
    }
    
}

Führt man das Projekt nun aus und lädt den entsprechenden View-Controller, wird eine Liste mit insgesamt zehn Zellen angezeigt, von denen jede ihre aktuelle Position widerspiegelt.

Die erstellte Table-View zeigt zehn einfache Einträge an.
Die erstellte Table-View zeigt zehn einfache Einträge an.

Fazit

Die Arbeit mit Table-Views wirkt insbesondere auf Einsteiger gerne sehr überfordernd. Neben der Klasse UITableView gibt es auch noch UITableViewCell und das UITableViewDataSource-Protokoll. Sieht man sich aber einmal in Ruhe deren jeweilige Funktionen und Anwendungszwecke an, verliert das Thema Table-View relativ schnell seinen Schrecken.

In diesem Artikel habt ihr die grundlegendsten Elemente bei der Arbeit mit der Klasse UITableView kennengelernt und erfahren, wie ihr eine einfache Liste erstellen könnt. Die folgenden Artikel dieser Reihe bauen darauf auf und werden das Thema Table-View noch weiter vertiefen.

Euer Thomas


Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert