Reputation: 17169
I have a static UITableView
setup in my storyboard. I have subclassed some cells and added this property:
@property (nonatomic, strong) UILabel *label;
I also have code to add the label to my cell in the layoutSubviews
method. My label shows in my cell without an issue. I can see the label saying 'PLACEHOLDER' but it is not updated to say the text I set in cellForRowAtIndexPath
.
In the cellForRowAtIndexPath
method, I have the following:
APInfoTableViewCell *cell = (APInfoTableViewCell*)[super tableView:tableView cellForRowAtIndexPath:indexPath];
[cell.label setText@"Hello World"];
However, this will not update the text in my label. The label is actually nil.
EDIT:
Here is the full code...
UITableViewCell
Subclass:
@property (nonatomic, strong) UILabel *infoLabel;
-(void)layoutSubviews
{
[super layoutSubviews];
[self initUI];
}
-(void)initUI
{
//add long press to show info label
_infoLabel = [UILabel new];
[_infoLabel setText:@"PLACEHOLDER"];
[_infoLabel setFont:[UIFont fontWithName:@"Avenir-Medium" size:10.0f]];
[_infoLabel setTextAlignment:NSTextAlignmentCenter];
[_infoLabel setTextColor:[UIColor apText]];
[_infoLabel setAlpha:1.0f];
[_infoLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self addSubview:_infoLabel];
NSArray *infoConstraintH = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-40-[infoLbl]-40-|" options:0 metrics:nil views:@{ @"infoLbl" : _infoLabel }];
[self addConstraints:infoConstraintH];
NSArray *infoConstraintV = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[infoLbl]-10-|" options:0 metrics:nil views:@{ @"infoLbl" : _infoLabel }];
[self addConstraints:infoConstraintV];
}
ViewController
:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
APInfoTableViewCell *cell = (APInfoTableViewCell*)[super tableView:tableView cellForRowAtIndexPath:indexPath];
[cell.infoLabel setText@"Hello World"];
return cell;
}
Upvotes: 0
Views: 47
Reputation: 1311
You need to instantiate a new cell in tableView:cellForRowAtIndexPath:
or use dequeueReusableCellWithIdentifier:
. cellForRowAtIndexPath:
returns visible instantiated cells in the table view. As you aren't instantiating your cells anywhere there are no cells in the table view, so cellForRowAtIndexPath:
returns nil
.
Additionally layoutSubviews
is called a lot and is called late. You should not rely on it to initialise your label. As it stands your cell will keep adding additional labels when ever layoutSubviews
is called! The designated initialiser is the place to add that initUI
code (as the name implies 😉). If your UITableViewCell
subclass doesn't use a XIB/Storyboard for its view, initWithStyle:reuseIdentifier:
is the designated initialiser. (Otherwise it is initWithCoder:
or awakeFromNib
)
Upvotes: 0
Reputation: 12839
If you are using storyboard, and you don't want to add IB outlet then call your initUI
method from awakeFromNib
method.
If you are not using storyboard implement - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
method and call it from there.
awakeFromNib method is called once the cell(or any UIView subclass) is instantiated from nib(either from storyboard or from xib). And its called only once in the lifetime of the view
Note: This will not get called if you are creating a view subclass programmatically.
As per documentation
Subclasses can override this method as needed to perform more precise layout of their subviews. You should override this method only if the autoresizing and constraint-based behaviors of the subviews do not offer the behavior you want. You can use your implementation to set the frame rectangles of your subviews directly.
That means, use this method to do any additional lay outing of already added. This method is called when some frame/autolayout constraint changes happens.
Upvotes: 1