UITableViewCell is Nil - iphone

I'm sure this question has a simple enough answer, but I can't seem to find it. I have the following code in my UITableViewController:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil)
{
NSLog(#"Cell is nil!");
}
return cell;
}
But in my log output I get
Cell is nil!
and immediately afterwards
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
* First throw call stack:
(0x1b68d72 0x135fe51 0x1b68bd8 0xb0e315 0xcb373 0x63578 0xcb1d3 0xcff19 0xcffcf 0xb9384 0xc952e 0x691bc 0x13736be 0x215c3b6 0x2150748 0x215055c 0x20ce7c4 0x20cf92f 0x2171da2 0x1b4b4 0x1be63 0x2c2be 0x2cf9f 0x1f3fd 0x1ac5f39 0x1ac5c10 0x1adeda5 0x1adeb12 0x1b0fb46 0x1b0eed4 0x1b0edab 0x1b28f 0x1ce71 0x253d 0x2465)
libc++abi.dylib: terminate called throwing an exception
(lldb)
Does anyone have any idea why this is happening, and more importantly, how to fix it?
Thanks in advance.

You must create cell if it nil, because method
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
return unused cell from table view cache.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:NSIndexPath*)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//configure cell
return cell;
}

dequeueReusableCellWithIdentifier returns an already created cell with the identifier you pass in, if one exists that can be reused.
If not, you're responsible for creating one.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCustomCellID];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:kCustomCellID] autorelease];
}

Yes, the methodUITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];means it will reuse a cell which has been allocated with the CellIdentifier.but you have not allocated any cells with this identifier, for the tableView, it will allocate some cells for a screen, and then it will reuse the cells with the identifier, if you do like this, you will find that it will work
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil)
{
NSLog(#"Cell is nil!");
cell = [[[UITableViewCell alloc] initWithSyle:UITableViewCellStyleNormal reuseIdentifier:CellIdentifier] autorelease];
}
return cell;
}
take a test.

Do you use interface builder for this class? If so, don't forget to make a reference from the table view. I had the same nil issue, and this was the case for me.

Related

Using Xcode 5 Storyboards to Build Dynamic TableViews with Prototype Table View Cells

I am trying to follow this tutorial but I am getting empty table.
http://www.techotopia.com/index.php/Using_Xcode_5_Storyboards_to_Build_Dynamic_TableViews_with_Prototype_Table_View_Cells
First, tutorial is using
{
CarTableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
}
with this I have encountered an error:
2013-11-12 11:29:35.940 TableViewStory[14940:70b] *** Terminating app due to uncaught
exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with
identifier carTableCell - must register a nib or a class for the identifier or connect a
prototype cell in a storyboard'
So I added:
[self.tableView registerClass:[CarTableViewCell class]
forCellReuseIdentifier:#"carTableCell"];
on my viewDidLoad. After adding the registerClass I was able to build my application. However I am getting empty table.
Thank you.
You need to implement cellForRowAtIndexPath method appropriately:
- (UITableViewCell *)tableView:(UITableView *)iTableView cellForRowAtIndexPath:(NSIndexPath *)iIndexPath
{
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [iTableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
// Customize your cell
return cell;
}
You didn't register a nib or a class for the reuse identifier CellIdentifier. You are using below piece
CarTableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
Replace this with
CarTableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
I re-did the tutorial and everything worked.
Thanks anyway.

Custom UITableViewCell content not moving when scrolling

I have a UITableView with a custom cell using Storyboards. All the objects inside the custom cell work but when I scroll in my UITableView the objects do not move:
Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableview cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"MainCell";
MainCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[MainCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.subtitle.text = [NSString stringWithFormat:#"%#",theEvent.startDate];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
Any ideas on what I have done wrong? Thanks.
I figured out the problem. The objects that I had placed on the UITableViewCell were not actually inside the cell but on top of the UITableView and therefore they were acting as "floating" objects.

UITableViewCell from IB Shows Value as NULL

The following is being used as the code to put a tableviewcell from a nib file into the tableview. I have taken the tableviewcell in the same nib as that of the tableview. I have tried initializing the cell in the viewdidload also but to no go.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"identifier";
NSLog(#"the cellidentifier is %#", CellIdentifier);
bookmarksTableViewCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSLog(#"the cell is %#", bookmarksTableViewCell);
return bookmarksTableViewCell;
}
The error that I get is
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
I have checked connections in the IB and rewired them too but the result comes up the same. When I try NSLog'ing the cell, it comes as null.
You need to do it like so
static NSString *CellIdenetifier = #"Cell";
BookMarksTableViewCell *cell = (BookMarksTableViewCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
cell = [[BookMarksTableViewCell alloc] initWithStyle:UITableViewCellStyleSubTitle reuseIdentifer:CellIdentifier];
}
Im not sure if you need that if but I thought I include it.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"identifier";
NSLog(#"the cellidentifier is %#", CellIdentifier);
bookmarksTableViewCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (bookmarksTableViewCell == nil){
//allocate your cell here
}
return bookmarksTableViewCell;
Of course it is null.
If a table view needs to display more cells than available in its queue, it returns nil from
dequeueReusableCellWithIdentifier:
to ask the data source for creating a new cell until the sufficient amount of cells are allocated. Check for NULL:
bookmarksTableViewCell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (bookmarksTableViewCell == NULL)
bookmarksTableViewCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStylePlain reuseIdentifier:cellIdentifier] autorelease];
return cell;
Ah, ps.: forget about Interface Builder.

dequeueReusableCellWithIdentifier not working with ARC and IOS 4

I can't seem to get dequeueReusableCellWithIdentifier working.
I need to build a project for IOS 4 so I can't use storyboards, but I'm using ARC.
Let's say I have 2 sections, each with 1 row.
Looking at the code below, I'm using the strong property to pass ownership, since ARC would insert the "autorelease" code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"TableCellIdentifier";
MainTableCell *cell = (MainTableCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
self.retainedCell = [[MainTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
However, for each row, cell is always nil (and hence a new MainTableCell is alloc'd) each time the function is called. The cell is never re-used.
This wouldn't be so much a problem except I programmatically call tableView:cellForRowAtIndexPath:, meaning I get a newly alloc'd cell each time, rather than the existing cell.
The only method I can see is to add the cells to an NSMutableArray.
Is there something I'm missing with dequeueReusableCellWithIdentifier now?
Thanks!
EDIT
I'm using the code below to get the cell. As mentioned it's creating a new cell not re-using the one that should have been already made + retained.
I don't need to invoke reloadData for all the rows, just change a specific one.
MainTableCell *cell = (MainTableCell *)[self tableView:self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[self configureCell:cell atIndexPath:indexPath];
You happen to be de-queuing MainTableCell, and then you proceed to check if it is nil, at which point you use a completely different var to alloc a table cell. What the heck? Try this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"TableCellIdentifier";
MainTableCell *cell = (MainTableCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[MainTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}

dequeueReusableCellWithIdentifier behavior changed for prototype cells?

In iOS5, using ARC and prototype cells for tableView on storyboard, can I replace the code below:
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
// Configure the cell...
return cell;
With this simple code??:
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:#"Cell"];
return cell;
I saw this on this link:
http://www.raywenderlich.com/5138/beginning-storyboards-in-ios-5-part-1
Thank's in advance!
Arildo
Sure, your code are right, storyboard automaticaly alloc new cells, this code work great:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
RoadbookCell *cell = (RoadbookCell *)[tableView dequeueReusableCellWithIdentifier:#"RoadbookCell"];
//Configure cell
//[cell.lab1 setText:#"Test"];
return cell;
}
This is the way Apple intends it to be used, but I recommend against it. There is a bug that causes dequeueReusableCellWithIdentifier to return nil when VoiceAssist is enabled on a device. That means your app will crash for users with this option turned on. This is still a problem as of iOS 5.1.1
You can find more info and a workaround here:
http://hsoienterprises.com/2012/02/05/uitableview-dequeuereusablecellwithidentifier-storyboard-and-voiceover-doesnt-work/
The last paragraph has the work-around