Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Styling custom UITableViewCell in initWithCoder: not working

I have some issues with a custom UITableViewCell and how to manage things using storyboards. When I put the styling code in initWithCoder: it doesn't work but if I put it in tableView: cellForRowAtIndexPath: it works. In storyboard I have a prototype cell with its class attribute set to my UITableViewCell custom class. Now the code in initWithCoder: does get called.

SimoTableViewCell.m

@implementation SimoTableViewCell

@synthesize mainLabel, subLabel;

-(id) initWithCoder:(NSCoder *)aDecoder {
    if ( !(self = [super initWithCoder:aDecoder]) ) return nil;

    [self styleCellBackground];
    //style the labels
    [self.mainLabel styleMainLabel];
    [self.subLabel styleSubLabel];

    return self;
}

@end

TableViewController.m

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

    //sets the text of the labels
    id<SimoListItem> item = (id<SimoListItem>) [self.places objectAtIndex:[indexPath row]];
    cell.mainLabel.text = [item mainString];
    cell.subLabel.text = [item subString];

    //move the labels so that they are centered horizontally
    float mainXPos = (CGRectGetWidth(cell.contentView.frame)/2 -      CGRectGetWidth(cell.mainLabel.frame)/2);
    float subXPos = (CGRectGetWidth(cell.contentView.frame)/2 - CGRectGetWidth(cell.subLabel.frame)/2);
    CGRect mainFrame = cell.mainLabel.frame;
    mainFrame.origin.x = mainXPos;
    cell.mainLabel.frame = mainFrame;
    CGRect subFrame = cell.subLabel.frame;
    subFrame.origin.x = subXPos;
    cell.subLabel.frame = subFrame;

    return cell;
}

I have debugged the code and found that the dequeue... is called first, then it goes into the initWithCoder: and then back to the view controller code. What is strange is that the address of the cell in memory changes between return self; and when it goes back to the controller. And if I move the styling code back to the view controller after dequeue... everything works fine. It's just I don't want to do unnecessary styling when reusing cells.

Cheers

like image 353
chopchop Avatar asked Jun 06 '13 02:06

chopchop


1 Answers

After initWithCoder: is called on the cell, the cell is created and has its properties set. But, the relationships in the XIB (the IBOutlets) on the cell are not yet complete. So when you try to use mainLabel, it's a nil reference.

Move your styling code to the awakeFromNib method instead. This method is called after the cell is both created and fully configured after unpacking the XIB.

like image 166
Wain Avatar answered Oct 11 '22 05:10

Wain