I am trying to use autolayout for a uitableviewcell subclass I am creating and I would appreciate some advice on what method to put the layout constraint creation code. I have been searching around and all the information I find talks about adding constraints after adding subviews in the viewDidLoad method. As far as I know viewDidLoad isn't an option for a uitableviewcell subclass.
I am using interface builder to create a custom cell and dynamically allocating it in my code. Nothing special there... I subclass the uitableviewcell so I can add a custom uiview to the cell. Again, nothing particularly Earth shattering... My difficulty comes when I try to position my custom uiview with respect to a label I added to the cell in interface builder.
This is the code to create the custom uiview and add it to the cell's content view:
- (id)initWithCoder:(NSCoder *)decoder
{
if ((self = [super initWithCoder:decoder]))
{
[self initSelf];
}
return self;
}
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]))
{
[self initSelf];
}
return self;
}
- (void) initSelf
{
// Initialization code
_badgeLabel = @"";
if (!_customBadge)
{
_customBadge = [CustomBadge customBadgeWithString:self.badgeLabel];
}
// hide the badge until needed
self.customBadge.hidden = YES;
// add badge to the cell view hierarchy
[self.customBadge setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.customBadge setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];
[self.customBadge setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisVertical];
[self.contentView addSubview:self.customBadge];
}
If I put the constraint code at the end of initSelf nothing happens. The position of my _customBadge stays at its' default. When I put the constraint code in layoutSubviews the positioning is applied; but I am pretty sure it is the wrong place. Here's the code:
- (void) layoutSubviews
{
[self.contentView addConstraint:[NSLayoutConstraint
constraintWithItem:self.customBadge
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:self.competence
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:-14.0]];
[self.contentView addConstraint:[NSLayoutConstraint
constraintWithItem:self.customBadge
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.competence
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0.0]];
[super layoutSubviews];
}
Can anyone tell me where this code should go? Surely I am creating duplicate constraints every time a layout happens.
Thanks
You would need to update constraints like:
-(void)updateConstraints{
// add your constraints if not already there
[super updateConstraints];
}
After adding your views to superview you need to call [self setNeedsUpdateConstraints]
to start using them. By doing so the rendering runtime will call updateConstraints
at the right time.