Reputation: 356
I'm struggling with this basic thing for more than a day and it drives me crazy! Funny thing is, I have very similar thing on other screen and it works just fine! I have done this a thousand times, but never experienced something so odd. Maybe is this behavior in iOS 8 only?
On my very simple Prototype cell I have two labels with tags 102 and 103. But when I want to set text to them, they are always nil.
I have double checked that identifier is correct and that tag is the same as in Storyboard.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString * identifier = @"secondReusableIdentifier";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
for (UIView *subview in [cell subviews]) {
NSLog(@"subview: %lu", subview.tag); // prints 0
}
UILabel * label1 = (UILabel *)[cell viewWithTag:102]; // returns nil
UILabel * label2 = (UILabel *)[cell viewWithTag:103]; // returns nil
if (self.items.count) {
MyObject *obj = [self.items objectAtIndex:indexPath.row];
label1.text = obj.someProperty;
fuelPrice2.text = obj.someOtherProperty;
}
}
return cell;
Any suggestions would be appreciated.
Upvotes: 2
Views: 3088
Reputation: 11197
Replacing this:
NSString * identifier = @"secondReusableIdentifier";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
BY
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"secondReusableIdentifier" forIndexPath:indexPath];
for creating a cell will solve your problem because, it always returns a cell. It either re uses existing cells or creates a new one and returns if there are no cells.
The most important difference is that the forIndexPath
: version crashes if you didn't register a class or nib for the identifier. The older (non-forIndexPath:) version returns nil in that case.
You must register a class or nib for using this. But if you create your table view and your cell prototypes in a storyboard, the storyboard loader takes care of registering the cell prototypes that you defined in the storyboard.
Hope this helps.. :)
Upvotes: 1
Reputation: 5047
In your code you are creating a new cell, that it's not the same than you have in Storyboard.
Change this: This is the old way, or the way you use when the cell is by code or nib, and you don't use storyboard. This code means.
NSString * identifier = @"secondReusableIdentifier";
// If I have available a cell with this identifier: secondReusableIdentifier, let's go to use it.
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil){
// If not, we create a new cell with this identifier. This methods is previous to storyboard, and this methods create a new cell, but does´t look in Storyboard if this identifier exist, or something like that.
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
To this, in other hand when Apple launched storyboard the framework grow with this methods, that work in this way: If there is a cell free use it, if not it look in Storyboard for a cell with this identifier and create a new cell with this info. (You can use this methods also by code and with nib file, but you must register the class before...).
// Be sure than: "secondReusableIdentifier", it's its identifier in storyboard
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"secondReusableIdentifier" forIndexPath:indexPath];
Upvotes: 2
Reputation: 4849
If
for (UIView *subview in [cell subviews]) {
NSLog(@"subview: %lu", subview.tag); // prints 0
}
prints 0, why do you do this??
UILabel * label1 = (UILabel *)[cell viewWithTag:102];
UILabel * label2 = (UILabel *)[cell viewWithTag:103];
So, if you created a custom cell with IB, you have to create a custom class and use it instead of a simple UITableViewCell
Upvotes: 0