How to work with two different custom cells in one tableView ? Using Storyboard, iOS 7

13,389

Solution 1

Beside you are returning nil for one of your cells, you also has an issue in numberOfRowsInSection, you are returning 0 rows for section 1!!, although you are expecting rows in this section in your cellForRowAtIndexPath.

Solution 2

I have made a test and it works fine. These are the steps:

  1. Create UITableViewController in storyBoard
  2. Drag and drop UITableViewCell on a UITableViewController below the cell that is already there
  3. Assign CellIdentifier to both cells (I used Cell1 and Cell2)
  4. Create 2 subclasses of UITableViewCell (I called them Cell1 and Cell2)
  5. Create subclass of UITableViewController and name it somehow
  6. in cellForRowAtIndexPath method:

    static NSString *CellIdentifier = @"Cell1";
    
    static NSString *CellIdentifier1 = @"Cell2";
    
    switch (indexPath.section) {
    
        case 0:
        {
            Cell1 *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
            return cell;
        }
            break;
        case 1:
        {
            Cell2 *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1 forIndexPath:indexPath];
            return cell;
        }
            break;
    
        default:
            break;
    

    }

    return nil;
    

As you can see the implementation is the same as yours

The only way I could reproduce your error is by returning nil in switch block and the documentation for dequeueReusableCellWithIdentifier says:

This method always returns a valid cell.

Even if you messed up your cell identifiers, you still wouldn't get the error you posted. So my conclusion is:

reboot, clean project, restart simulator or something like that cause your scenario according to documentation is not possible...

Share:
13,389

Related videos on Youtube

JuanM.
Author by

JuanM.

https://1ma.dev

Updated on June 04, 2022

Comments

  • JuanM.
    JuanM. almost 2 years

    I have two custom cells. And I want to display 2 sections in my UITableView. The first section with one row displaying the first custom cell, and the second section displaying a list of objects pulled from core data.

    How should I implement the "cellForRowAtIndexpath" method ?

    Here is some of my code:

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
    
    // Return the number of sections.
    return 2;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
    
    // Return the number of rows in the section.
    if (section == 0) {
        return 1;
    
    } else if (section == 1) {
       //gastos is an array
       return [self.gastos count];  
    }
    return 0;
    }
    
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath         *)indexPath
    {
    
    switch (indexPath.section) {
        case 0:
        {
            SaldoCelda *cell1 = [tableView dequeueReusableCellWithIdentifier:@"Cell1"      forIndexPath:indexPath];
            return cell1;
        }
        case 1:
        {
            static NSString *CellIdentifier = @"Cell";
            CeldaGasto *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier      forIndexPath:indexPath];
    
            NSManagedObject *gasto = [self.gastos objectAtIndex:indexPath.row];
    
            [cell.monto setText:[NSString stringWithFormat:@"%@ AR$", [gasto valueForKey:@"monto"]]];
            [cell.categoria setText:[NSString stringWithFormat:@"%@", [gasto valueForKey:@"categoria"]]];
            [cell.fecha setText:[NSString stringWithFormat:@"%@", [gasto valueForKey:@"fecha"]]];
    
            return cell;
        }
        default:
            break;
    }
    return 0;
    }
    

    And this is the error message I get:

    Assertion failure in -[UITableView _configureCellForDisplay:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2903.23/UITableView.m:6246 2014-03-05 01:02:57.181 Spendings[2897:70b] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'

    Thankyou for your help!

    • rmaddy
      rmaddy about 10 years
      Read the error. You are returning nil for your cellForRowAtIndexPath: method. It's either case 0 or case 1. Use the debugger and see which one is the problem.
    • rmaddy
      rmaddy about 10 years
      BTW - a little side note - there is no need for the break statements in your switch for the cases that end in return. The break statements will never be reached in those cases.
  • rmaddy
    rmaddy about 10 years
    While the implementation of numberOfRowsInSection: is incorrect as you point out, that really has nothing to do with the crash. But it does narrow down the problem in cellForRowAtIndexPath: to the case 0: code.
  • Tarek Hallak
    Tarek Hallak about 10 years
    hmmm, agree 100% ;) but still yet another issue he should take care of it.
  • JuanM.
    JuanM. about 10 years
    OK, I just fix that, but my problem still goes. The section 0 is only having one row as I want, and the section 1 has the count of "gastos".
  • rmaddy
    rmaddy about 10 years
    But you haven't fixed the fact that you return nil in case 0 of your cellForRowAtIndexPath method. The call to [tableView dequeueReusableCellWithIdentifier:@"Cell1" forIndexPath:indexPath]; is returning nil. Did you register the cell for that index path? Did you register it with the name Cell1?
  • Tarek Hallak
    Tarek Hallak about 10 years
    As @rmaddy mentioned in his comment you need to do some debugging, check why your cell is nil, most likely the Cell Identifier, start from there.
  • JuanM.
    JuanM. about 10 years
    Or could it be a storyboard problem ? I have my table view with content of "static cells" with sections equals to "2" in Storyboard editor. And the first section with its only cell is registered as Cell1 in its identifier.
  • rmaddy
    rmaddy about 10 years
    None of these changes are needed and it actually makes the code more confusing. And none of it fixes the problem.
  • Tarek Hallak
    Tarek Hallak about 10 years
    First the table is not a "static cells" content which has nothing to do with your problem (ignored I guess), second you need to create a prototype cell for section 2 and register it as "Cell" or init it inside your cellForRowAtIndexPath.
  • Charan Giri
    Charan Giri about 10 years
    @rmaddy which part of code made you confused? return 0; means you are returning nil to cell and rows...
  • JuanM.
    JuanM. about 10 years
    Ok, that is helping. Now I do not get any error message. But I got another problem, my first custom cell has the size of the second custom cell.
  • rmaddy
    rmaddy about 10 years
    I'm not confused. The return is never reached. The table has two sections. Therefore case 0 and case 1 of the switch handles the two sections. Both create and return a cell. The default is never reached. The return at the end of the method is never reached. The OP's code is much cleaner than your proposal.
  • Tarek Hallak
    Tarek Hallak about 10 years
    Glad for that, man the cell height is another story, change it using the delegate:- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexpathe.section == 0 && indexpathe.row == 0) return 50.0; return 100; }
  • JuanM.
    JuanM. about 10 years
    Thank you Charan, but I already solved part of my problem in the answers before. I got what you say @rmaddy about the return is never reached.
  • JuanM.
    JuanM. about 10 years
    Awesome! That really worked! I just compared the values that I had to return with the heights that I had made in the storyboard editor! Thanks a lot to you @null and rmaddy.
  • JuanM.
    JuanM. about 10 years
    I think the use of XIB files is outdated, and with xCode 5 and iOS 7 everything works with storyboard.
  • JuanM.
    JuanM. about 10 years
  • Charan Giri
    Charan Giri about 10 years
    @rmaddy when switch conditions are true The default is never reached. will it? in section 0 and 1 i'm assigning cell1 to cell and cell2 to cell and returning it at the end as return cell; break is used to just break the switch not the cell configure method. so it will reach return cell statement. If i'm wrong on this can you please explain it
  • rmaddy
    rmaddy about 10 years
    Sorry, I was talking about the OP's code. My whole point is that your suggested change is unnecessary as well as more complicated. And more importantly, it in no way solves the problem.
  • Jissay
    Jissay about 10 years
    I actually work with XIB files for creating cells, loading is simplier and focusing better when working on your cell design. But i understand you want to use only Storyboard Maybe you should still give it a try.
  • Gourav Gupta
    Gourav Gupta about 10 years
    you can do the same thing with the help of storyboard. In case of storyboard you have to get cell's nib from your storyboard file.