IOS/Autolayout:在生命周期中为代码中创建的元素设置约束
Posted
技术标签:
【中文标题】IOS/Autolayout:在生命周期中为代码中创建的元素设置约束【英文标题】:IOS/Autolayout: When in lifecycle to set constraints for elements created in code 【发布时间】:2018-01-04 22:22:40 【问题描述】:我的大部分场景都在情节提要中并使用自动布局。但我想在代码中创建一个 UITableView、标签和视图,并将它们限制在整个 autlayout 中。我的问题是我应该在生命周期的哪个位置创建约束。
现在,我在 ViewDidLoad 中创建元素的隐藏版本,然后根据数据在 View Will Appear 中自定义和显示它们。我认为我不能将布局约束放在 ViewDidLoad 中,因为编译器不会知道故事板中的所有视图都位于何处。另一方面,我不想在每次 viewWillAppear 触发时重新创建这些约束。大多数都不会改变,最多我可能想更新一两个。
我是否应该将约束放在 viewWillAppear 中,并在某个测试中创建它们是否已经创建?还是应该将它们放在其他地方,例如 viewDidlayoutSubviews 或 viewDidAppear?
感谢您的任何建议。
这是创建约束的代码:
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];
【问题讨论】:
【参考方案1】:任何以编程方式创建的约束都应放在 viewDidLayoutSubviews 中,并用一次 bool 值包装,因为在启动 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];
【讨论】:
以上是关于IOS/Autolayout:在生命周期中为代码中创建的元素设置约束的主要内容,如果未能解决你的问题,请参考以下文章