24.05.2012

Xcode 4, iPhone, , Cocoa Touch, iOS5

Tutorial: UITableViewController mit Custom Cells iOS5

In diesem Tutorial wird erklärt, wie eine eigene UITableViewCell erstellt und im UITableViewController verwendet wird. Die in dem Beispiel erstellte TableCell besteht aus einem UIImage und drei UILabels. Es ist anzumerken, daß dieses Beispiel nur mit iOS5 oder neuer läuft. In dem verlinkten Tutorial ist beschrieben, wie eine Lösung für iOS4 aussehen kann: Tutorial: UITableViewController mit Custom Cells iOS4.

Die fertige Beispielapplikation sieht folgendermaßen aus:

Gestartet wird mit dem Anlegen einer iOS Application (⌘+⇧+N). In dem Fenster wählt man unter iOS den Eintrag Application aus. Als Template wird Empty Application selektiert.

Create New Project

Als Product Name für die App verwenden wir TableViewCustomCell.

Create New Project

Abschließend wird ein Projekt-Verzeichnis gewählt.

Create New Project

Nach dem Klick auf Create öffnet Xcode das neue Projekt.

Create New Project

Nun wird eine Klasse für die UITableViewCell mit ⌘+N angelegt. In dem Fenster wählt man unter iOS den Eintrag Cocoa Touch aus. Als Template wird Objective-C class selektiert und mit Next bestätigt.

Create New Project

Als Namen für die Class wählt man MyTableViewCell und als Subclass of die Klasse UITableViewCell und klickt danach auf Next.

Create New Project

Dann wird mit Create die Klasse erzeugt.

Create New Project

Nun wird eine Xib-Datei für die die UITableViewCell mit ⌘+N angelegt. In dem Fenster wählt man unter iOS den Eintrag User Interface aus. Als Template wird Empty selektiert und mit Next bestätigt.

Create New Project

Als Device Family läßt man unverändert iPhone stehen und bestätigt den Dialog mit Next.

Create New Project

Unter Save As: wird den Name der Xib-Datei eingetragen. Man wählt MyTableViewCell und schließt den Dialog mit Create

Create New Project

Nun öffnet sich der Interface Builder mit einer leeren Ansicht. Dort sucht man in der Object Library nach Table und zieht eine Table View Cell nach links in Oberfläche. Anschließend wird ober der Identity Inspector ausgewählt und als Class der Wert MyTableViewCell eingetragen.

Create New Project

Anschließend wird in der Object Library nach UIImage gesucht und diese in die UITableViewCell gezogen. Nach dem gleichen Muster werden drei UILabels in die Zelle eingefügt. Bei iOS4 mußte noch für jedes Label ein Tag vergeben werden, damit die einzelnen Labels später wieder gefunden werden können. Das entfällt bei iOS5!

Create New Project

Für die Xib-Datei müssen jetzt Outlets zu der Klasse MyTableViewCell angelegt werden. Dazu schaltet man zu dem Assistent Editor mit ⌥⌘↩ um. Auf der linken Seite sollte die Xib-Datei angezeigt werden und auf der rechten Seite die Header-Datei von MyTableViewCell. Mit ctrl-Drag werden die Elemente der Zelle nun in die Header-Datei gezogen, um die Outlets anzulegen. Im folgenden Screenshot ist das für das UIImage zu sehen.

Create New Project

Für das UIImage trägt man als Namen den Wert cellImage ein.

Create New Project

Für alle anderen Elemente in der Zelle verfährt man genauso. Die Header-Datei sollte danach folgendermaßen aussehen:

//
//  MyTableViewCell.h
//  TableViewCustomCell
//
//  Created by Jörn Hameister on 24.05.12.
//  Copyright (c) 2012 http://www.hameister.org. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface MyTableViewCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UIImageView *cellImage;
@property (weak, nonatomic) IBOutlet UILabel *mainLabel;
@property (weak, nonatomic) IBOutlet UILabel *dateLabel;
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;

@end

Nun wird der ViewController mit ⌘+N angelegt. In dem Fenster wählt man unter iOS den Eintrag Cocoa Touch aus. Als Template wird Objective-C class selektiert und mit Next bestätigt.

Create New Project

Als Namen für die Class wählt man ViewController und klickt auf Next.

Create New Project

Dann wird mit Create die Klasse erzeugt.

Create New Project

In der Header-Datei des ViewControllers muß von der Klasse UITableViewController erben:

//
//  ViewController.h
//  TableViewCustomCell
//
//  Created by Jörn Hameister on 24.05.12.
//  Copyright (c) 2012 http://www.hameister.org. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface ViewController : UITableViewController

@end

Als nächstes wird die Datei ViewController.m angepaßt. Als erstes muß die Xib-Datei mit der Zelle in der Methode viewDidLoad geladen werden. Um die UITableView zu füllen, müssen zwei Methoden des UITableViewDataSourceProtokolls implementiert werden. Einmal die Methode tableView:cellForRowAtIndexPath:, die die UITableViewCell zurückliefert. Und die Methode tableView:numberOfRowsInSection:, die die Anzahl der Zeilen festlegt. Die Angabe des DataSource-Protokolls konnte in der Header-Datei übrigens weggelassen werden, weil sie automatisch auf self gesetzt werden, wenn zu einem ViewController keine Xib-Datei existiert.

In der Methode viewDidLoad wird die Xib-Datei geladen und bei der UITableView registriert. Dieses Feature steht erst ab der iOS-Version 5 zur Verfügung (UITableView registerNib:forCellReuseIdentifier:). Wenn man also rückwärtskompatibel zu iOS4 sein möchte, muß der in Tutorial: UITableViewController mit Custom Cells iOS4 beschriebene Weg gewählt werden.

In der Methode tableView:cellForRowAtIndexPath: wird auf dem Standardweg eine UITableViewCell angelegt (siehe auch Tutorial: UITableViewController). Da wir eben unsere CustomCell registriert haben, können wir davon ausgehen, daß ein Objekt vom Typ MyTableViewCell zurückgeliefert wird. Da wir ein Objekt mit dem konkreten Typ in der Hand haben, können wir direkt die setter der Zelle aufrufen. Die Namen entsprechen denen, die wir beim Anlegen der Outlets vergeben haben. Für die beiden Labels auf der rechten Seite wird das Datum und die Uhrzeit mittels eines NSDataFormatters als Text gesetzt. Für das Hauptlabel wird einfach die Zeilennummer angegeben. Zum Schluß wird das UIImage mit [UIImage imageNamed:@"TwitterIcon.png"] der Tabellenzelle zugewiesen. Das zu ladende Icon muß sind innerhalb des Xcode-Projekts befinden.

//
//  ViewController.m
//  TableViewCustomCell
//
//  Created by Jörn Hameister on 24.05.12.
//  Copyright (c) 2012 http://www.hameister.org. All rights reserved.
//

#import "ViewController.h"
#import "MyTableViewCell.h"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UINib *nib = [UINib nibWithNibName:@"MyTableViewCell" bundle:nil];
    // iOS 5.0 and later !!!
    [[self tableView] registerNib:nib forCellReuseIdentifier:@"MyTableViewCell"];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    MyTableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"MyTableViewCell"];
    NSDateFormatter *dateFormatter = [NSDateFormatter new];
    
    cell.mainLabel.text = [NSString stringWithFormat:@"Zeile %d", [indexPath row]];
    
    
    [dateFormatter setDateFormat:@"dd.MM.yyyy"];
    cell.dateLabel.text = [NSString stringWithFormat:@"%@", [dateFormatter stringFromDate:[NSDate date]]];
    
    [dateFormatter setDateFormat:@"HH:mm:ss"];
    cell.timeLabel.text = [NSString stringWithFormat:@"%@", [dateFormatter stringFromDate:[NSDate date]]];
    
    cell.cellImage.image = [UIImage imageNamed:@"TwitterIcon.png"];
    
    return cell;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 500;
}
@end

Abschließend muß nur noch die Datei AppDelegate.m angepaßt werden, so daß der ViewController beim Starten der App als RootViewController verwendet wird. Dazu muß die Import-Anweisung ergänzt werden und die Methode application:didFinishLaunchingWithOptions: folgendermaßen angepaßt werden:

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

Nach dem Kompilieren und Starten mit ⌘+R öffnet sich der Simulator und zeigt die UITableView mit den Custom-Cells.

Beim Scrollen in der TableView bemerkt man an der Uhrzeit, daß die Zellen erst dann erstellt werden, wenn sie in das Sichtfeld scrollen.