Reputation: 1654
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
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
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
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