Most of my scene is in storyboard and uses autolayout. But I want to create a UITableView, label and view in code and constrain them within the overall autlayout. My question is where in the lifecycle should I create the constraints.
Right now, I create hidden versions of the elements in ViewDidLoad and then customize and display them in View Will Appear based on data. I don't think I can put the layout constraints in ViewDidLoad, because the compiler won't know where all the views from storyboard are located. On the other hand, I don't want to recreate these constraints everytime viewWillAppear fires. Most don't change and at most I might want to update one or two.
Should I place the constraints in viewWillAppear and condition creating them on some test whether they were already created? Or should I put them somewhere else such as viewDidlayoutSubviews or viewDidAppear?
Thanks for any suggestions.
This is the code that creates the constraints:
NSLayoutConstraint *contop = [NSLayoutConstraint constraintWithItem:_stepsTableView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_stepNames attribute:NSLayoutAttributeBottom multiplier:1 constant:12];
NSLayoutConstraint *contrail = [NSLayoutConstraint
constraintWithItem:_stepsTableView attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual toItem:self.scrollView
attribute:NSLayoutAttributeTrailing multiplier:1 constant:20];
NSLayoutConstraint *conlead = [NSLayoutConstraint
constraintWithItem:_stepsTableView attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual toItem:self.scrollView
attribute:NSLayoutAttributeLeading multiplier:1 constant:20];
NSLayoutConstraint *conbot = [NSLayoutConstraint
constraintWithItem:_stepsTableView attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual toItem:self.scrollView
attribute:NSLayoutAttributeBottom multiplier:1 constant:20];
NSLayoutConstraint *conheight = [NSLayoutConstraint constraintWithItem:_stepsTableView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:height];
[self.scrollView removeConstraint: _bottomConstraint];
[self.scrollView addConstraints:@[contop,contrail,conlead,conbot,conheight]];
[self.view layoutIfNeeded];
Any programmatically created constraints should be placed in viewDidLayoutSubviews and wraped with once bool value as the function is being called multiple times during launch of a viewController
-(void)viewDidLayoutSubviews
{
if(once){
once = NO;
_stepsTableView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *contop = [NSLayoutConstraint constraintWithItem:_stepsTableView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_stepNames attribute:NSLayoutAttributeBottom multiplier:1 constant:12];
NSLayoutConstraint *contrail = [NSLayoutConstraint
constraintWithItem:_stepsTableView attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual toItem:self.scrollView
attribute:NSLayoutAttributeTrailing multiplier:1 constant:20];
NSLayoutConstraint *conlead = [NSLayoutConstraint
constraintWithItem:_stepsTableView attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual toItem:self.scrollView
attribute:NSLayoutAttributeLeading multiplier:1 constant:20];
NSLayoutConstraint *conbot = [NSLayoutConstraint
constraintWithItem:_stepsTableView attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual toItem:self.scrollView
attribute:NSLayoutAttributeBottom multiplier:1 constant:20];
NSLayoutConstraint *conheight = [NSLayoutConstraint constraintWithItem:_stepsTableView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:height];
[self.scrollView removeConstraint: _bottomConstraint];
[self.scrollView addConstraints:@[contop,contrail,conlead,conbot,conheight]];
[self.view layoutIfNeeded];
}
}