Hallo Zusammen,
heute programmieren wir das Grundgerüst einer Kontaktverwaltung. Natürlich möchten wir nicht einfach alle Kontakte schlicht in einer Tabelle untereinander reihen. Die Kontakte sollen stattdessen durch eine Sektion mit ihren jeweiligen Anfangsbuchstabe getrennt sein. Am Ende sieht das ganze dann so aus:
Zunächst machen wir uns ein paare Gedanken um die Datenstruktur:
- Ausgangspunkt ist ein Array mit allen Namen, die wir anzeigen möchten – contactsArray
- Aus den Kontakten im contactsArray lesen wir die Anfangsbuchstaben aus und speichern Sie in einem – letterArray. Dieses nutzen wir dann unter anderem im den Sektionen einen Namen zu geben. Natürlich achten wir darauf wir keine Buchstaben anzuzeigen zu denen es keine Namen gibt.
- Zu guter letzt bauen wir uns eine Dictionary auf. Die einzelnen Buchstaben werden die Keys im Dictionary, wohinter sich dann Arrays mit allen Namen zu diesem Buchstaben befindet. Das ganze nennen wir segmentDictionary
Als Ausgangspunkt soll uns ein neues Projekt vom Typ „Single View Application“ dienen. Die mitgelieferte ViewController wird gelöscht. Nun erstellen wir über New » File einen UITableViewController mit dem Namen „TableViewController“.
Wechseln wir in das Storyboard begegnet uns ein einsamer ViewController – auch der wird gelöscht. Wir ziehen einen TableViewController ins Storyboard. Diesen TableViewController betten wir nun in einen NavigationController ein (Editor » Embed In » Navigation Controller). Über den Identity Inspector ändern wir die Klassen des TableViewController in die vorher angelegte „TableViewController“ Klasse. Und da wir gerade in der Ecke sind markieren wir die Zelle, stellen Sie auf Basic und vergeben den Reuse Identifier „ContactCell“.
Das soll es mit der Vorbereitung gewesen sein – jetzt können wir Quellcode schreiben. Als erstes ergänzen wir die oben beschriebenen properties im TableViewController Header.
@property (nonatomic, strong) NSArray *contactsArray; @property (nonatomic, strong) NSMutableDictionary *segmentDict; @property (nonatomic, strong) NSMutableArray *letterArray;
In viewDidLoad erstellen wir unsere arrays und rufen anschließend createDatastructure auf.
self.contactsArray = [NSArray arrayWithObjects:@"Albert",@"Anne",@"Bernd",@"Boris",@"Claus", @"Peter", nil]; self.segmentDict = [NSMutableDictionary dictionary]; self.letterArray = [NSMutableArray array]; [self createDatastructure];
createDatastructure baut die oben bereits erwähnte Datenstruktur auf. Wir haben bisher zwar ein NSMutableDictionary erstellt, aber es ist ja alles noch leer.
-(void)createDatastructure { // 1 for (NSString *contact in self.contactsArray) { // 2 NSString *firstLetter = [[contact substringToIndex:1] uppercaseString]; // 3 if (![self.letterArray containsObject:firstLetter]) { [self.letterArray addObject:firstLetter]; // create a new Array and add it to the Dict NSMutableArray *newArray = [NSMutableArray array]; [newArray addObject:contact]; [self.segmentDict setValue:newArray forKey:firstLetter]; }else { // 4 // add contact to array in dict NSMutableArray *fetchArray = [self.segmentDict objectForKey:firstLetter]; [fetchArray addObject:contact]; } } }
Schauen wir uns das der Reihe nach an:
- Wir starten eine Schleife und lesen die Strings aus dem contacsArray aus.
- den ersten Buchstaben eines jeden Namens trennen wir ab und verwandeln ihn in einen Großbuchstaben. Falls es schon einer ist – egal. Das ganze merken wir uns unter der Variable firstLetter.
- Wir prüfen ob firstLetter bereits im letterArray enthalten ist. Ist das nicht der Fall bedeutet es, dass wir einen Namen mit diesem Anfangsbuchstaben bisher noch nicht hatten. Wir fügen den Buchstaben zum letterArray hinzu. Außerdem müssen wir unter diesem Buchstaben-Schlüssel einen entsprechenden Eintrag im segmentDictionary anlegen.
- Falls der Buchstabe hingegen bereits im letterArray enthalten ist, holen wir uns einfach das entsprechende Array auf dem Dictionary und fügen den Namen ein.
Jetzt wo unsere Datenstruktur steht ist der Rest Standard TableView Handhabung.
Die Anzahl der Sektionen entspricht der Einträge im letterArray.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return [self.letterArray count]; }
Der Text einer Sektion ist gleich dem Eintrag im letterArray an ebendieser Stelle. So ist der Text der zweiten Sektion gleich dem zweiten Eintrag gleich „B“.
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { return [self.letterArray objectAtIndex:section]; }
Die Anzahl der Zeilen in einer Sektion ist gleich der Einträge im Array des segmentDictionarys für den Schlüssel dieser Sektion. Denken wir uns also die Sektion 1, so bekommen wir das B aus dem letterArray ausgelesen. Dieses B ist gleichzeitig ein Schlüssel im segmentDictionary. Die Anzahl des aus dem Dictionary enthaltene Arrays gibt nun die Anzahl der Zeilen in dieser Sektion an.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { NSString *sectionTitle = [self.letterArray objectAtIndex:section]; NSArray *fetchArray = [self.segmentDict objectForKey:sectionTitle]; return [fetchArray count]; }
Zu guter letzt erstellen wir die Zellen. Dabei benutzen wir den anfangs vergebenen Reuse Identifier „ContactCell“. Wir gehen ansonsten genauso vor wie schon unter numberOfRowsInSection – nur mit dem zusätzlichen Schritt, dass wir die Namen aus dem fetchArray auch den Text der Zellen zuweisen.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ContactCell" forIndexPath:indexPath]; NSString *sectionTitle = [self.letterArray objectAtIndex:indexPath.section]; NSArray *fetchArray = [self.segmentDict objectForKey:sectionTitle]; NSString *contact = [fetchArray objectAtIndex:indexPath.row]; cell.textLabel.text = contact; return cell; }
Geschafft. Ihr solltet nun diese Ergebnis sehen. Ich habe noch einmal die benutzte Datenstruktur mit eingezeichnet.
1 thought on “Tutorial: Grundgerüst Kontakte App”