I am trying to create a table view which uses two types of cells – default and subtitle.
I tried to use a single reusable cell (*cell) which seemed to work fine until I got to the bottom cell which was off screen – when this came into view it was a duplicate of the first visible cell.
I thought that I could try to add a second type of cell (*cellB) and when I did it seemed to solve the problem however it would crash every so often with the following error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
I know that I am doing something wrong and I am pretty sure I am not implementing the reusable cells properly but after several days of frustration I would really appreciate some advice.
P.S. I have searched many previous posts but none seem to cover the issue of using two types of cells on the same table.
Thanks in advance.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
UITableViewCell *cellB = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCellB"];
switch (indexPath.section) {
case 0:
if (cell == nil) {
// The only subtitle cell
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:@"UITableViewCell"];
}
[[cell textLabel] setText:title];
[[cell textLabel] setTextColor:[UIColor whiteColor]];
[[cell detailTextLabel] setText:[NSString stringWithFormat:@"Entry: £%@",price]];
[[cell detailTextLabel] setTextColor:[UIColor colorWithWhite:1.0 alpha:.8]];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
break;
case 1:
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"UITableViewCell"];
UIView *cellBackView = [[UIView alloc] initWithFrame:CGRectZero];
cellBackView.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed:@"PhotoFrame.png"]];
cell.backgroundView = cellBackView;
}
[lImage setFrame:CGRectMake(0, 23, 320, 200)];
[cell.contentView addSubview:lImage];
break;
case 2:
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"UITableViewCell"];
UIView *cellBackView = [[UIView alloc] initWithFrame:CGRectZero];
cellBackView.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed:@"PaperTop.png"]];
cell.backgroundView = cellBackView;
}
break;
case 3:
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"UITableViewCell"];
UIView *cellBackView = [[UIView alloc] initWithFrame:CGRectZero];
cellBackView.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed:@"Paper.png"]];
cell.backgroundView = cellBackView;
}
break;
case 4:
// I'm pretty sure this bit is wrong but if I use (cell == nil) the first cell is shown instead
if (cellB == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"UITableViewCellB"];
UIView *cellBackView = [[UIView alloc] initWithFrame:CGRectZero];
cellBackView.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed:@"PaperBottom.png"]];
cell.backgroundView = cellBackView;
}
break;
default:
break;
}
return cell;
}
As cgull pointed out, when
[indexPath section]is4, you’re initializingcellB, but still returningcell, which may or may not have a valid cell in it.You need to have one variable that holds the cell you’re going to return, no matter the path taken through the
switch: