NCFUSN
NCFUSN

Reputation: 1654

iOS 5, Storyboards, ARC: UITableview doesn't get populated with data from custom delegate and datasource

This is my first time I am working on UITableView connected to custom delegate and datasource. Until today, I used to connect to "self". The prequel for this question is here.

So, I have two additional UIViews. Using segmented control I put one of the over mentioned UIViews on self.view...

Have created two UITableView subclasses and set them as delegate and datasource. Works fine, no leaks or crashes. Checked if the classes getting initialized on segmentedControl index change:

- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
    // Custom initialization
    NSLog(@"Nominals got init");
}
return self;
}

NSLog works when changing segment.

The question:

In my custom delegate class I override the methods required by UITableViewDelegate and UITableViewDataSource protocols.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 20;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UILabel *lbl=[[UILabel alloc]initWithFrame:CGRectMake(12, 12, 200, 12)];
lbl.text=@"some nominal";
cell.textLabel.text=@"Nominal";
[cell addSubview:lbl];

return cell;
}

At moment I am getting exception:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'

Well, isn't the cell in my custom delegated class is the same cell of my UITableView I've created:

-(void)populateNominals:(int)subCountryID
{
NominalsTableViewDelegate *del=[[NominalsTableViewDelegate alloc]init];
[self setNominalsDelegate:del];


UITableView *nominalsTableView=[[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 372) style:UITableViewStylePlain];

[nominalsTableView setDelegate:nominalsDelegate];
[nominalsTableView setDataSource:nominalsDelegate];
[nominalsTableView reloadData];
[self.nominalsView addSubview:nominalsTableView];

}

what's my mistake? Thank you in advance.

Upvotes: 0

Views: 565

Answers (3)

Sj.
Sj.

Reputation: 1724

the dequeueReusableCellWithIdentifier will return UITableViewCell instances when the cells are being reused while scrolling through the tableView.

So add

if (nil == cell)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

You have to use the initWithStyle:reuseIdentifier: which is the designated initializer for tableview cells.

Upvotes: 0

Bruno Koga
Bruno Koga

Reputation: 3874

On your tableView:cellForRowAtIndexPath: method, you are missing the case where there are no cells to be dequeued. Take a look at your code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    UILabel *lbl=[[UILabel alloc]initWithFrame:CGRectMake(12, 12, 200, 12)];
    lbl.text=@"some nominal";
    cell.textLabel.text=@"Nominal";
    [cell addSubview:lbl];

    return cell;
}

You should do something like:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (!cell) {
        cell = [[UITableViewCell alloc] init];
    }

    UILabel *lbl=[[UILabel alloc]initWithFrame:CGRectMake(12, 12, 200, 12)];
    lbl.text=@"some nominal";
    cell.textLabel.text=@"Nominal";
    [cell addSubview:lbl];

    return cell;
}

because by doing that, if you can't dequeue a cell, you're creating a new one.

Upvotes: 1

Midhun MP
Midhun MP

Reputation: 107231

You aretrying to dequeue a cell using dequeueReusableCellWithIdentifier. If there is no cell in the queue what happens ? Definitely crash.

So you need to allocate a cell, add this line too:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
 cell = [[UITableViewCell alloc] init];
}

Upvotes: 3

Related Questions