Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is UITableViewCell initialization not working inside initWithCoder

I'm trying to clean up my code and use MVC principles by pushing as much view related stuff as i can into the storyboard as well as custom UIView classes (ie as opposed to doing view related stuff on the UIViewController itself)

So I have a custom UITableViewCell (called CustomCell) that has several properties, one of them is my own label. Since I'm loading the cell from the storyboard, I initialize it with initWithCoder rather than initWithStyle:reuseIdentifier:, this is what I have in CustomCell.m which is a subclass of UITableViewCell (for some reason i couldn't figure out how to set a custom font using storyboard.. but that's beside the point of this question):

// CustomCell.m - subclass of UITableViewCell
- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        NSLog(@"customizing cell font having text %@", self.label.text);
        UIFont *customFont = [UIFont fontWithName:@"Montserrat" size:16];
        self.label.textColor = [UIColor redColor];
        [self.label setFont:customFont];
    }
    return self;
}

This simply doesn't work.. the log statement outputs null for the text simply b/c the text hasn't been loaded yet. self.label is also null (I don't know why I thought it should have been inflated from the nib by now) but even if I initialize it here.. it still won't work.

So my work around was to simply put this cell customization part here in the TableViewController:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell 
forRowAtIndexPath:(NSIndexPath *)indexPath {        
    UIFont *customFont = [UIFont fontWithName:@"Montserrat" size:16];
    [((CustomCell *)cell).label setFont:customFont];
}

and it worked just fine.. I'm unhappy with this method and I would like to know how to make it work from within CustomCell.m

update: to make things even more interesting.. if i put customization code for UITableViewCell properties inside initWithCoder, they work! consider this example:

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        UIView *bgColorView = [[UIView alloc] init];
        [bgColorView setBackgroundColor:[UIColor blueColor]];
        [self setSelectedBackgroundView:bgColorView];  // actually works!
    }
    return self;
}

which makes this even more weird.

like image 737
abbood Avatar asked Mar 21 '23 20:03

abbood


1 Answers

Inspired by andykkt's comment, I found the explanation in awakeFromNib documentation:

The nib-loading infrastructure sends an awakeFromNib message to each object recreated from a nib archive, but only after all the objects in the archive have been loaded and initialized. When an object receives an awakeFromNib message, it is guaranteed to have all its outlet and action connections already established.

so that explains the weird behaviour above: initWithCoder instantiates a standard UITableViewCell (that already comes pre-baked with a backgroundView etc etc).. however it still doesn't recognize the outlets I've added to it via storyboard.. awakeFromNib does.

like image 87
abbood Avatar answered Apr 26 '23 04:04

abbood