Table View Controllers

Et UITableView får dataene og oppførselen sin fra en UITableViewController.

UITableViewController implementerer protokollene UITableViewDelegate og UITableViewDataSource

@interface UITableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
...
@end

Når UITableViewController skal trenger informasjon om hvilke data som skal vises (hvor mange rader? hva er innholdet i cella?) spør den sin UITableViewDataSource om dette. Tilsvarende spør den UITableViewDelegate om oppførsel (kan man trykke på cellen? hvor høy skal raden være?)

Delegate patternet

Måten UITableViewController spør UITableViewDelegate og UITableViewDataSource er et eksempel på bruk av delegate patternet

Eksempel på UITableViewController

SpotifySearchResultTableViewController.h
@interface SpotifySearchResultTableViewController : UITableViewController
@end
SpotifySearchResultTableViewController.m
I dokumentasjonen til UITableViewDataSource vil du se at vi minimum må implementere to metoder:
#import "SpotifySearchResultTableViewController.h"
#import "SpotifyService.h"
#import "SpotifyTrack.h"

@interface SpotifySearchResultTableViewController ()
@property (nonatomic, strong) NSArray* tracks;
@end

@implementation SpotifySearchResultTableViewController
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.tracks.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"trackCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    SpotifyTrack *track = self.tracks[indexPath.row];
    cell.textLabel.text = track.title;
    cell.detailTextLabel.text = track.artist;
    
    return cell;
}
@end

dequeueReusableCellWithIdentifier?

static NSString *CellIdentifier = @"trackCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

Disse linjene ser kanskje kryptiske ut, men er helt geniale! Det som skjer i praksis er at Cocoa Touch prøver å finne en celle som allerede er laget og scrollet ut av skjermen med IDen trackCell. Hvis det finnes en slik celle, blir den den gjenbrukt slik at man slipper å instansiere en ny og holde denne i minnet. Finnes den ikke blir det allokert et nytt UI celle for deg. Dette betyr at selv om du har en array med 1000 elementer, vil det aldri finnes flere UI celler enn man får plass til på skjermen.

Linke opp cell identifier mot Storyboard

Dersom du har et storyboard med et UITableView må du sette cellen til å ha samme cell identifier som du har i koden din (eks. trackCell som vist over). Dette gjør du ved å:
  1. Klikke på cellen i Document Outline
  2. Bytte til Attribute inspectoren (se rød sirkel rundt knapp)
  3. Skrive inn identifier

Sette seg selv til delegate i Interface builder

For at delegatefunksjonene til UITableViewDelegate og UITableViewDataSource skal bli kalt (og tabellen din fungere), må UITableViewet sette seg som delegate. Dette gjør du slik:
  1. Klikke på table viewet i Document Outline
  2. Bytte til Connections inspectoren
  3. Klikk i sirklen for delegate ved siden av datasource og dra en linje som du slipper på viewcontrolleren (se bilde). Gjenta for dataSource delegatet.