Combine static and prototype content in a table view

Solution 1:

I suggest you treat your table as dynamic, but include the cells you always want at the top. In the Storyboard, place a UITableViewController and have it use a dynamic table. Add as many UITableViewCell prototypes to the table as you need. Say, one each for your static cells, and one to represent the variable cells.

In your UITableViewDataSource class:

#define NUMBER_OF_STATIC_CELLS  3

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.dynamicModel count] + NUMBER_OF_STATIC_CELLS;
}

and, then

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    if (indexPath.row < NUMBER_OF_STATIC_CELLS) {
        // dequeue and configure my static cell for indexPath.row
        NSString *cellIdentifier = ... // id for one of my static cells
    } else {
        // normal dynamic logic here
        NSString *cellIdentifier = @"DynamicCellID"
        // dequeue and configure for [self.myDynamicModel objectAtIndex:indexPath.row]
    }
}

Solution 2:

I had a problem, although it was a slight variant of this. I actually wanted to mix dynamic and static cells but in different groups. Meaning group 1 would have static only cells and group 2 would have dynamic cells.

I accomplished this by actually hard coding static cell values (based on their prototype cell identifiers). The dynamic sections would have normal dynamically populated content. Here is some example code in case anyone else has the same issue:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{    
    if (section == 1){
        return @"Dynamic Cells";
    }
    if (section == 0){
        return @"Static Cells";
    }
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == 0) {
        return 1; //However many static cells you want
    } else {
        return [_yourArray count];
    }
}

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
    if (indexPath.section == 0) {
        NSString *cellIdentifier = @"staticCellType";   
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        }

        cell.textLabel.text = @"some static content";        
        return cell;

    } else if (indexPath.section == 1){

        NSString *cellIdentifier = @"dynamicCellType";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        }

        cell.textLabel.text = [_yourArray objectAtIndex:indexPath.row];
        return cell;

    } 
    return nil;

}

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