Display multiple custom cells in a UITableView?

I am using Xcode 4.2 on SnowLeopard, and my project is using storyboards. I am trying to implement a UITableView with 2 different custom cell types, sessionCelland infoCell. I can get the 2 types to appear within the same list, but now I have a new problem?! The sessionCell is displayed once, and then X number of infoCells are displayed after it – just as I wanted – except that the first infoCell is always overwritten by the sessionCell!

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

//inside cellForRowAtIndexPath
    if(indexPath.row == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:@"sessionCell"];
} else {
cell = [tableView dequeueReusableCellWithIdentifier:@"infoCell"];
}
...
return cell;

I’ve tried to say return array count + 1, or even hardcoded return 7 (it fits my example) but both are incorrect!

  • Obj-C: Memory Leak of Malloc 48 bytes in strdup frame
  • Objective-C : How to fetch the router address?
  • Order the Output of NSMutableDictionary like the Input
  • Google Analytics 3.12 crashes on iOS
  • Reading audio samples via AVAssetReader
  • How to display the UITableView programmatically?
  • myObject *person = [self.people objectAtIndex:indexPath.row];
    

    Or does my problem lie in the above line? I’ve even tried indexPath.row+1

    Any help would be greatly appreciated!!

    2 Solutions Collect From Internet About “Display multiple custom cells in a UITableView?”

    If I understand your question correctly, the first infoCell (second UITableView row) should display the first person object’s data, right?

    Then it seems you want:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *sessionCellID = @"sessionID";
        static NSString *infoCellID = @"infoID";
    
        if( indexPath.row == 0 ) {
            SessionCellClass *cell = nil;
            cell = (SessionCellClass *)[tableView dequeueReusableCellWithIdentifier:sessionCellID];
            if( !cell ) {
                //  do something to create a new instance of cell
                //  either alloc/initWithStyle or load via UINib
            }
            //  populate the cell with session model
            return cell;
        }
        else {
            InfoCellClass *cell = nil;
            cell = (InfoCellClass *)[tableView dequeueReusableCellWithIdentifier:infoCellID];
            if( !cell ) {
                //  do something to create a new instance of info cell
                //  either alloc/initWithStyle or load via UINib
                // ...
    
                //  get the model object:
                myObject *person = [[self people] objectAtIndex:indexPath.row - 1];
    
                //  populate the cell with that model object
                //  ...
                return cell;
            }
        }
    

    and you need to return [[self people] count] + 1 for the row count:

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return [[self people] count] + 1;
    }
    

    so that the n’th row shows the (n-1)th data.

    if you look at the if else section it shows that the first row is an “sessionCell” and all other rows are “infoCells” what i think you want to do is make the first row an sessionCell, the second row an infoCell and all of the other rows peopleCells

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return [self.people count] + 2; // Added two for sessionCell & infoCell
    }
    
    //inside cellForRowAtIndexPath
    if(indexPath.row == 0) {
        cell = [tableView dequeueReusableCellWithIdentifier:@"sessionCell"];
    } else if (indexPath.row == 1 {
        cell = [tableView dequeueReusableCellWithIdentifier:@"infoCell"];
    } else {
        cell = [tableView dequeueReusableCellWithIdentifier:@"personCell"];
        Person *person = [self.people objectAtIndex:index.path.row - 2];
    }
    
    ...
    return cell;
    

    Better yet, I would try to make two different sell sections, one for info and one for people

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        return 2;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return section == 0 ? 2 : self.people.count
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        UITableViewCell = nil;
        if (indexPath.section == 0) {
            if(indexPath.row == 0) {
                cell = [tableView dequeueReusableCellWithIdentifier:@"sessionCell"];
                // configure session cell
            } else if (indexPath.row == 1 {
                cell = [tableView dequeueReusableCellWithIdentifier:@"infoCell"];
                // configure info cell
            }
        } else {
             cell = [tableView dequeueReusableCellWithIdentifier:@"infoCell"];
             Person *person = [self.people objectAtIndexPath:indexPath.row];
             // configure person cell
        }
    
        return cell;
    }