Here’s a bare bones, stripped down version of the mechanics behind a UITableView with sections.


#import "MyTableViewController.h"

@interface MyTableViewController ()

@end

@implementation MyTableViewController

@synthesize data1 = _data1;
@synthesize data2 = _data2;

- (NSArray *)data1 {
    if (_data1 == nil) {
        _data1 = [NSArray arrayWithObjects:@"a", @"b", nil];
    }
    return _data1;
}

- (NSArray *)data2 {
    if (_data2 == nil) {
        _data2 = [NSArray arrayWithObjects:@"x", @"y", @"z",nil];
    }
    return _data2;
}

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 2;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == 0)
        return self.data1.count;
    if (section == 1)
        return self.data2.count;
    return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
    if (indexPath.section == 0)
        cell.textLabel.text = [self.data1 objectAtIndex:indexPath.row];
  
    if (indexPath.section == 1)
        cell.textLabel.text = [self.data2 objectAtIndex:indexPath.row];
    
    return cell;
}


#pragma stuff I added

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    if (section == 0)
        return @"section1";
    if (section == 1)
        return @"section2";
    return @"undefined";
}

@end

Note1: All cell access is 0 indexed.

Note2: This is for demo purposes only. If you were to do this for real you’d probably want to do something like this.