0

I have created a .xib file which has more than 2 tableview cells. I used the following code in the viewDidLoad() method for registering nib to reuse cells.

UINib *nib = [UINib nibWithNibName:@"CartTableViewCells" bundle:nil];
[self.tableView registerNib:nib forCellReuseIdentifier:@"Cell0"];
[self.tableView registerNib:nib forCellReuseIdentifier:@"Cell1"];
[self.tableView registerNib:nib forCellReuseIdentifier:@"Cell2"];

And In - [UITableView CellForRowAtIndexPath] method, I used the following code.

cell0 = (CartTableViewCells *)[self.tableView dequeueReusableCellWithIdentifier:@"Cell0"];
if (cell0==nil)
{
    cell0 = [[[NSBundle mainBundle] loadNibNamed:@"CartTableViewCells" owner:self options:nil] objectAtIndex:0];
}

But My app crashed with the following error:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'invalid nib registered for identifier (Cell0) - nib must contain exactly one top level object which must be a UITableViewCell instance'

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • if you are using the same nib for all your rows, just register once. are you using the cell tableview template to create your nib? I think that the structure of the cell is wrong. – Lucho Mar 17 '16 at 14:05
  • a couple of links with similar problems http://stackoverflow.com/questions/18639099/nib-must-contain-exactly-one-top-level-object-which-must-be-a-uitableviewcell-in – Lucho Mar 17 '16 at 14:06
  • http://stackoverflow.com/questions/20442311/invalid-nib-registered-for-identifier-cellname-nib-must-contain-exactly-one – Lucho Mar 17 '16 at 14:06
  • 2
    I am using same nib but the nib file has 3 tableviewcells with 3 different reuse identifier and using the 3 cells for different rows. – Micheal Vijayaraj Mar 17 '16 at 14:10
  • You have a nib with 3 cells inside? I usually have 1 nib with one cell. Maybe using `[[NSBundle mainBundle] loadNibNamed: owner: options:]` this returns an array, i don't know if you would have each cell on diff position of the array. Something like this : `NSArray *nibs = [[NSBundle mainBundle] loadNibNamed:@"mynib" owner:self options:nil]; UINib *nib = [nibs objectAtIndex:0] [self.tableView registerNib:nib forCellReuseIdentifier:@"Cell0"];` You have to do the same for the rest of the nibs on the array – Lucho Mar 17 '16 at 15:18
  • The problem is NSArray *nibs has an array of the custom cell instances only. I cannot register it with the nib. – Micheal Vijayaraj Mar 17 '16 at 18:23
  • I use a lot of custom cells, but I create a new nib and file for each cell. I would suggest that if the cells are all doing something different -- even if they are just displaying slightly different information in slightly different ways -- then having a separate nib for each will make your code much cleaner in the long run. You just create a cell for the cart type (I assume that some will have images, others might have other data to be shown). Pass it the data object...then let the cell deal with how to display it. – Mike Critchley Mar 17 '16 at 19:14

1 Answers1

0

You can do this, provided you have some way of distinguishing the views in your XIB (tags, custom classes, etc). You don't even need to register the nib – all you have to do is this:

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSInteger cellIndex = 12345;
    NSString *cellIdentifier = @"MyAwesomeCell";

    // dequeue cell or, if it doesn't exist yet, create a new one from the nib
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (!cell)
    {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"MyNibWithLotsOfCustomCells" owner:self options:nil];
        NSUInteger index = [topLevelObjects indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
            // if you distinguish the views by class
            return [obj isMemberOfClass:NSClassFromString(cellIdentifier)];
            // if you distinguish the views by tag
            return [(UIView*)obj tag] == cellIndex;
        }];
        cell = topLevelObjects[index];
    }

    // etc.
}

It's important to use dequeueReusableCellWithIdentifier: and not dequeueReusableVellWithIdentifier:forIndexPath: (the difference is explained in this thread).

Community
  • 1
  • 1
deltacrux
  • 1,186
  • 11
  • 18