uitableview-tutorial

5

Click here to load reader

Upload: dirkkoller

Post on 10-Jul-2015

205 views

Category:

Software


0 download

TRANSCRIPT

Page 1: UITableView-Tutorial

UITableView-Tutorial – CocoaBitscocoabits.de /ios/uitableview-tutorial

Dirk Koller

Tabellen sind sehr wichtige Komponenten in der iOS-Entwicklung und finden praktisch in jedem ProjektEinsatz. Die Möglichkeiten der UITableView sind beeindruckend vielseitig, das Tutorial konzentriertsich deshalb auf die gängigsten Anwendungsfälle: CRUD sprich Create, Read, Update und Delete mitCustom Zellen und das Umsortieren von Zellen. Die Screenshots zeigen eine iPhone-App, abernatürlich funktioniert das Ganze für das iPad ebenso.

Table View Controller BasicsGestartet wird mit der Projektvorlage Empty Application (File > New > Project… > iOS > Application >Empty Application). Die leere Anwendung wird durch eine neue Klasse UserTableController (File >New > File… > iOS > Cocoa Touch > Objective-Class) erbend von UITableViewController ergänzt. EinXib-File dafür wird nicht benötigt. Die Tabelle soll die Liste der Benutzer anzeigen. Damit der neuangelegte Table View Controller (bzw. dessen Table View) angezeigt wird, ist zunächst eine Instanz derKlasse als Root View Controller im AppDelegate zu setzen. Wir gehen hier gleich noch einen Schrittweiter und packen den UserTableController in einen Navigation Controller. Die dadurch erzeugteNavigation Bar bietet Platz für Buttons (bzw. Bar Button Items) und ist erforderlich für den Wechselzum Benutzer Detail View.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; UserTableController *tableViewController = [[UserTableController alloc] init]; UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:tableViewController]; self.window.rootViewController = navigationController; // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES;}

Die Datenquelle: Table View Data Source

Im Zusammenhang mit Table Views existieren zwei wichtige Protokolle: UITableViewDataSource undUITableViewDelegate. Während die Data Source für das Bereitstellen der Daten zuständig ist, geht esbeim Delegate um Aussehen und Aktionen der Tabelle.

Die Superklasse UITableViewController implementiert die beiden erforderlichen Methoden desProtokolls UITableViewDataSource (numberOfSectionsInTableView: und tableView:numberOfRowsInSection:). Diese müssen im UserTableController überschrieben werden. Wirentfernen die Warnings und geben Daten aus einem als Property gehaltenen und in viewDidLoadgefülltem Array zurück:

Page 2: UITableView-Tutorial

@property (nonatomic) NSMutableArray *data;..._data = [NSMutableArray arrayWithArray:@[@"Maier", @"Müller", @"Schmidt"]];...- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1;}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.data.count;}

Durch die Änderungen werden jetzt drei Zellen einer Sektion abgefragt. Die Inhalte der Zelle werden intableView:cellForRowAtIndexPath: festgelegt:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuseIdentifier" forIndexPath:indexPath]; cell.textLabel.text = [self.data objectAtIndex:indexPath.row]; return cell;}

Man beachte im obigen Codeabschnitt dass die MethodedequeueReusableCellWithIdentifier:forIndexPath: verwendet wird. Tabellenzellen werden ausSpeicher- und Performancegründen in einer Queue gespeichert, wenn sie den sichtbaren Bereichverlassen. Die genannte Methode erzeugt die Zellen selbständig, wenn noch keine Zellen in der Queuevorliegen. Sie benötigt dafür allerdings die Information, von welchem Typ die zu erzeugenden Zellensein sollen. Diese wird in viewDidLoad durch Aufruf der TableView-MethoderegisterClass:forCellReuseIdentifier: gegeben:

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"reuseIdentifier"];

Ein erster Start der App zeigt die drei Zellen mit den Namen der Benutzer.

Page 3: UITableView-Tutorial

Zellen selektieren: Table View Delegate

Das andere bereits genannte Protokoll im Zusammenhang mit Table Views ist das Table ViewDelegate. Es ist zuständig für Aussehen und Verhalten der Tabelle. Alle darin aufgeführten Methodensind optional. Die Wichtigste ist tableView:didSelectRowAtIndexPath:, sie wird aufgerufen beim Tapauf eine Zelle. In der Methode wird zum Beispiel der Wechsel in einen Detail View Controllerausprogrammiert. Mit Hilfe des übergebenen Index Path lässt sich das passende Datenobjekt ermittelnund einem Detail Controller (hier UserDetailController) übergeben:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { UserDetailController *userDetailController = [[UserDetailController alloc] init]; userDetailController.lastName = [self.data objectAtIndex:indexPath.row]; [self presentViewController:userDetailController animated:YES completion:^{ // }];}

Styles und Custom ZellenDie Standard-Table View Cell kommt in vier verschiedenen Varianten (UITableViewCellStyle) daher, indenen maximal zwei Labels und ein Bild verschieden angeordnet angezeigt werden können. DerVorteil dieser Styles ist, dass sie vom Aussehen her bekannten Apple Apps entsprechen und keineeigenen Zellen-Klassen erzeugt werden müssen. Möchte man einen der Stile verwenden, müssen dieZellen mit der älteren Methode dequeueReusableCellWithIdentifier: (Achtung: ohne forIndexPath:) ausder Queue geholt werden. Die Zellen werden dabei nicht automatisch erzeugt, dies geschieht danachmit alloc/initWithStyle:reuseIdentifier:. Bei dieser Variante muss das Registrieren der Zelle entferntwerden, der Typ wird beim alloc angegeben.

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuseIdentifier"]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"reuseIdentifier"]; } cell.detailTextLabel.text = [self.data objectAtIndex:indexPath.row];

Genügen die vier vordefinierten CellTypen den Anforderungen nicht, können eigene Zellen erzeugtwerden.

Dazu legt man eine Subklasse von UITableViewCell an (etwa UserCell). Außerdem wird ein leeres Xib(am besten mit gleichem Namen wie die Subklasse) benötigt. In das Xib wird eine Table View Cell ausder Komponentenbibliothek gezogen. Die Custom Class der zugefügten Zelle (nicht des Files Owner!)wird auf den Namen der zuvor angelegten Subklasse UserCell gesetzt. Darüber hinaus wird der CellIdentifier im Inspektor gesetzt (etwa UserCellIdentifier). Die Zelle kann danach mit den gewünschtenControls (Labels usw.) gestaltet werden. Damit man die zugefügten Labels auch setzen kann, werdennoch Outlets in der UserCell angelegt (Connections über die Zelle und nicht den File’s Owner!!!).

Eigene Zellen müssen im Code registriert werden - wenn ein Nib-File vorhanden ist, über die MethoderegisterNib:forCellReuseIdentifier: des Table View.

Page 4: UITableView-Tutorial

[self.tableView registerNib:[UINib nibWithNibName:@"MyCell" bundle:nil] forCellReuseIdentifier:@"Cell"];

Danach kann die Zelle am einfachsten mit der oben bereits beschriebenen neueren Variante derdequeue-Methode ermittelt werden.

Löschen und der Edit ModeDer Table View Controller verfügt über einen eingebauten Edit-Modus. Er lässt sich leicht mit Hilfe deseditButtonItem in der Navigation Bar einbinden:

self.navigationItem.rightBarButtonItem = self.editButtonItem;

Ein Tab auf Bearbeiten animiert die Löschen-Button von der linken Seite der Zellen ein und ändert dieBeschriftung des editButtonItems von Bearbeiten auf Erledigt bzw. Done im Englischen.

Das Löschen der Daten erfolgt in der Methode tableView:commitEditingStyle:forRowAtIndexPath:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { // Delete the row from the data source [self.data removeObjectAtIndex:indexPath.row]; // Delete the row from the table view [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; } else if (editingStyle == UITableViewCellEditingStyleInsert) { // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view } }

Page 5: UITableView-Tutorial

Verschieben von ZellenDer Edit-Mode hilft auch beim Verschieben von Zellen. Er blendet die Verschiebe-Handles auf derrechten Seite der Zelle automatisch ein:

Voraussetzung dafür ist, dass die betroffene Zelle auch wirklich verschoben werden darf. Dies wird intableView:canMoveRowAtIndexPath: pro Zelle oder auch pauschal für alle Zellen festgelegt:

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { // Return NO if you do not want the item to be re-orderable. return YES;}

Weiterhin muss in der Methode tableView:moveRowAtIndexPath:toIndexPath: das Verschieben derZelle im Datenmodell implementiert werden. Wenn die Zelle im UI verschoben wurde, sollte diesnatürlich auch in dem zugrunde liegenden Array geschehen:

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { id object = [self.data objectAtIndex:fromIndexPath.row]; [self.data removeObjectAtIndex:fromIndexPath.row]; [self.data insertObject:object atIndex:toIndexPath.row]; [self.tableView reloadData];}

Zum WeiterlesenTable View Programming Guide for iOS