Einstieg in NSTableView

Wer sich mit iOS-Programmierung beschäftigt, wird früher oder später mit einer TableView konfrontiert werden. Es handelt sich dabei um eine Instanz der Klasse UITableView, einer Subklasse von UIScrollView, die wiederum eine Subklasse von UIView ist.

Wie verhält es sich aber mit einer TableView in der Cocoa-Programmierung für OS X? Hierfür existiert die Klasse NSTableView, die in diesem Beitrag näher betrachtet werden soll. Werfen wir dafür zunächst einen Blick auf die Klassenhierarchie:

NSTableView Hierarchy

Wenn man eine TableView implementieren möchte, muss man sich klar machen, dass sie selbst keine Daten hält. Vielmehr verhält es sich so, dass sie die Daten, die sie darstellen soll, von einer data source abruft. Für iOS-Programmierer ist das nichts Neues, schließlich verhält es sich dort ebenso.

Die Verwendung einer TableView erfordert daher, dass sie dem NSTableViewDataSource Protocol entspricht. Es müssen folglich die entsprechenden Methoden dieses Protokolls implementiert werden.

Folgendes Beispiel soll dies verdeutlichen:

Startet Xcode und wählt “Create a new Xcode project” aus.

Klickt zunächst auf „macOS“ und wählt dann “Cocoa Application” aus.

Create new Cocoa project

Nun gebt Ihr eurem Projekt einen Namen (hier: NSTableViewExample) und passt die übrigen Felder (Organization Name, Organisation Identifier) an. Achtet darauf, als Sprache “Swift” auszuwählen und bei “Use Storyboards” ein Häkchen zu setzen.

Create Xcode Project

Im nächsten Fenster könnt Ihr dann den Speicherort des Projektes bestimmen. Da wir kein Repository verwenden möchten, soll bei “Create Git repository on” kein Häkchen gesetzt sein.

Werfen wir zunächst ein Blick auf das Storyboard; dazu klickt bitte im Project Navigator auf Main.Storyboard.

empty view controller in a storyboard

Beginnen wir damit, unserem Programmfenster einen anderen Namen zu geben. In der linken Outline-Spalte wählt man dazu unter “Window Controller Scene / Window Controller” das Programmfenster “Window” aus. Im Attributes Inspector auf der rechten Seite kann dann unter Title eine andere Bezeichnung vergeben werden. Hier ändere ich “Window” zu “NSTableViewExample”.

change window name in storyboard

Nun startet Euer Programm mit cmd + R (oder: -> Product -> Run). Ihr seht das Fenster der Anwendung mit der von Euch vergebenen Bezeichnung. Beendet das Programm wieder.

Im Storyboard muss nun eine *TableView von der Object Library auf die leere View gezogen werden.

add a NSTableView in storyboard

Da wir lediglich eine Tabellenspalte benötigen, wählt Ihr anschließend im Outline-Bereich die zweite Table Column aus und entfernt sie.

outline view in storyboard

Es ist zudem ratsam, darauf zu achten, dass die TableView in der View zumindest links, oben und unten zusammen mit den blauen Hilfslinien, die Xcode anzeigt, abschließt.

In der Kopfzeile der TableView ist immer noch die Trennlinie für zwei Spalten zu sehen. Wenn Ihr im Outline-Bereich “Table Header View” auswählt, könnt Ihr diese Trennlinie – bei gedrückter linker Maustaste – nach rechts rüberziehen, bis tatsächlich nur noch eine Spalte vorhanden ist. Anschließend führt Ihr auf der Kopfzeile einen Doppelklick durch, so dass nun ein Spaltenname vergeben werden kann (hier: Städte). Die View sollte nun wie folgt aussehen:

NSTableView in Storyboard

Weiter geht es mit Code: Öffnet dazu im Project Navigator die Datei “ViewController.swift”. Zunächst soll – direkt am Anfang der Klasse ViewController ein Array mit vier Städten erzeugt werden:

class ViewController: NSViewController {

    let townArray = ["Flensburg", "Münster", "Bielefeld", "Nürnberg"]

    ...

Und nun geht es daran, diese Städte in der TableView anzuzeigen. Wie bereits oben erwähnt, bedarf es dazu einer data source. In diesem Beispiel ist das die ViewController-Klasse, was bedeutet, dass in dieser Klasse die Methoden des NSDataSourceProtocols implementiert werden müssen. Legt also fest, dass Eure Klasse diesem Protokoll entsprechen soll:

class ViewController: NSViewController, NSTableViewDataSource {

    ...

}

Im Storyboard muss anschließend eine entsprechende Verknüpfung erzeugt werden: Dafür klickt Ihr im Outline-Bereich mit der rechten Maustaste auf TableView, worauf sich ein weiteres Fenster öffnet. Sucht unter Outlets die dataSource und zieht dann bei gedrückter linker Maustaste vom Kreis hinter dataSource eine Linie zum View Controller.

connect the data source in storyboard

Bei Erfolg wird dann die nunmehr vorhandene Verknüpfung angezeigt:

dataSource connection

Zurück in der Datei “ViewController.swift” werden jetzt die erforderlichen Methoden des NSDataSourceProtocols hinzugefügt, wobei Euch die Ähnlichkeit zu numberOfRowsInSection aus der iOS-Programmierung ins Auge fallen dürfte.

// MARK: NSTableViewDataSource
func numberOfRows(in tableView: NSTableView) -> Int {
    return townArray.count
}

func tableView(_ tableView: NSTableView, objectValueFor tableColumn: 
    NSTableColumn?, row: Int) -> Any? {

    let town = townArray[row]
    return town
}
NSTableView without cocoa bindings

Startet nun das Programm (cmd + R) und stellt fest, dass wir noch nicht am Ziel sind:

Denn anstatt der Städtenamen wird lediglich “Table View Cell” ausgegeben. Das ist schon mal nicht schlecht, denn es bedeutet, dass die TableView mit der data source verknüpft ist. Schließlich wird für jede Table Cell View von der data source ein Objekt zurückgeliefert und als „Table View Cell“ angezeigt. Wie erreichen wir nun aber, dass auch die Städtenamen erscheinen?

Nun verfügt Table Cell View (oder besser gesagt: NSTableViewCell) über die Eigenschaft (Property) objectValue. Das von der data source zurückgegebene Objekt wird eben auf diese Eigenschaft gesetzt. — Damit nun tatsächlich die Städtenamen angezeigt werden, bedarf es eines weiteren Schritts: Es müssen Cocoa Bindings genutzt werden, damit die Eigenschaft objectValue mit den Table View Cells, die den Text darstellen sollen, verknüpft werden. Erst dann erscheinen in den (hier: vier) Table View Cells die Städtenamen aus unserem townArray.

Der Weg zum Ziel führt uns zunächst in den Outline-Bereich des Storyboards. Dort wählt Ihr im Abschnitt „View Controller Scene“ die Table View Cell aus.

TableViewCell

Anschließend öffnet Ihr im rechten Utility-Bereich den Bindings Inspector. Setzt dort ein Häkchen bei “Bind to Table Cell View” und achtet darauf, dass bei “Model Key Path” auch objectValue eingetragen ist.

NSTableView Bindings

Nun startet das Projekt erneut. Ihr werdet feststellen, dass die Städte in der TableView angezeigt werden.

Finished NSTableView

Und damit sind wir am Ende angekommen. Ich hoffe, dass Euch dieser kleine Beitrag als Einstieg zur NSTableView weiterhelfen konnte.

Zuletzt aktualisiert am 28. September 2016