Cocoa – UITableView

These are a  few notes on creating the UITableView. Understand at the time of writing this, I’m a total beginner, so take everything here with a grain salt, and an once of skepticism. The purpose of writing this is to settle subject in my own brain.

As part of the MVC pattern UITableView is a View, so a table view knows how to draw itself. A table view typically needs a view Controller to manage it. A table view always needs a data source. The data source supplies, the number of section, rows, and the content for each row. Typically a table view needs a Delegate. The Delegate handles events generated by the table view.

An instance of the UITableViewController class can handle the role of Controller, Data Source, and Delegate. The UITableViewController, as a view controller, manages a view and this view is always a UITableView.

Any class that manages a UITableView must be a UITableViewDelegate. The data source for the UITableView must be a UITableViewDataSource. These are often the same class, I’m guessing  they don’t have to be.

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

@end

This is the UITableView Protocol

To display the UITableView these requirements must be met.

UITableViewDataSource

This protocol requires two methods be implemented:

-(NSInteger)tableView:numberOfRowsInSection
-(UITableViewCell *)tableView:cellForRowAtIndexPath

These two methods tell the UITableView how many cells to work with, and give you the opportunity to populate and configure the UITableViewCells.

Giving the table view the number of rows in a section allows it to get data via the index of that row. Without having to contain the actual data. Essentially tableView:numberOfRowsInSection tells the table view how many cells you will need to work with. When comes time to display a cell, the table view calls on tableView:cellForRowAtIndexPath passing the index of the cell, this function returns the cell; and within this function you populate and configure the cell.

-(NSInteger)tableView:numberOfRowsInSection

This method is relatively simple. It returns the number of cells in the table view. If you were using an array you might implement it in this way:

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [array count];
}

– (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

The cell For Row method is more complex. Here is where table cells are created, populated, and configured. The table creates cells only as needed. It only creates enough actual cells to fill the screen. As cells scroll up the page they are recycled and repopulated with new data, with the tableview keeping track of which index is currently visible. This process makes the system much more memory efficient, since the computer holds only a limited number of cells in memory. Imagine your iTunes library with 500, or 1000, or more songs. The table view is really only working with enough cells to fill the screen, maybe 10. If the computer to generate 1000 or more table cells, it would slow down, and become unresponsive. Using this system, the table view is recycling a limited number cells like an escalator, changing the content as the cell moves off the top of the view and reappears at the bottom of the view.

You might implement this method as:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *simpleTableIndenitfier = @"SimpleTableCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIndenitfier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIndenitfier];
    }
    
    cell.textLabel.text = [recipes objectAtIndex:indexPath.row];
    return cell;
}

Here the dequeueReusableCellWithIdenifier asks for an available cell from the table, which is stored in cell. If cell is nil, no cell was available, so a new cell is generated. In this case the cell is generated using the UITableViewCell alloc. Then initialized with initWithStyle. Here we tell initWithStyle to use one of the default cell styles UITableViewCellStyleDefault.

– (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

This method tells the table view how many sections you will using. Be sure to set this to at least 1. The default implementation of this methods is set 0.

Storyboard and outlets

To connect a tableview created in storyboard to it’s view controller’s outlets, Control drag from the tableView to the view controller and choose dataSource. Repeat the process for delegate. You want the Outlets dataSource and delegate to read ViewController.