在Xcode 8 iOS项目中调用layoutIfNeeded
内的viewDidLoad
是否安全,如下面的代码?
- (void)viewDidLoad {
[super viewDidLoad];
[self.view layoutIfNeeded];
CGFloat frameHeight = CGRectGetHeight(self.frame);
subview.layer.cornerRadius = frameHeight * 0.5;
}
它在没有layoutIfNeeded
的Xcode 7中正常工作。
答案 0 :(得分:5)
如果您遇到问题,可以在viewDidLayoutSubviews()中调用它。
来自Apple iOS 10发行说明:
发送layoutIfNeeded到视图不会移动视图,但在早期版本中,如果视图已将translateOutoresizingMaskIntoConstraints设置为NO,并且如果它是通过约束定位的,则layoutIfNeeded将移动视图以匹配布局引擎之前将布局发送到子树。这些更改纠正了这种行为,接收者的位置及其大小通常不受layoutIfNeeded的影响。
某些现有代码可能依赖于现在已更正的此错误行为。在iOS 10之前链接的二进制文件没有行为更改,但是在iOS 10上构建时,您可能需要通过将-layoutIfNeeded发送到前一个接收器的translatesAutoresizingMaskIntoConstraints视图的超级视图来纠正某些情况,或者之前定位和调整它的大小(或之后,取决于您所希望的行为)layoutIfNeeded。
使用自动布局的自定义UIView子类的第三方应用程序在调用超级之前覆盖layoutSubviews和self上的脏布局有可能在iOS 10上重建时触发布局反馈循环。当正确发送后续layoutSubviews调用时,它们必须一定要在某些时候停止弄脏自己的布局(注意在iOS 10之前的版本中跳过了这个调用)。“
基本上你不能在View的子对象上调用layoutIfNeeded - 现在调用layoutIfNeeded必须在superView上,你仍然可以在viewDidLayoutSubviews中调用它。
答案 1 :(得分:2)
我认为更好的方法是在viewWillAppear
或viewDidLayoutSubviews
那些是框架实际完成的时间。 viewDidLayoutSubviews
很好,因为它会对视图框架中的更改做出反应。
答案 2 :(得分:2)
如果您要求针对不同尺寸类别使用不同的cornerRadius
值,我会使用traitCollectionDidChange
代替viewWillLayoutSubviews
或viewDidLayoutSubviews
。
override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?)
。如果首次加载视图,则previousTraitCollection
将为nil
。
这样,如果您的应用程序支持多任务处理,只要视图大小更改为同时在您的设备屏幕上显示两个应用程序,您的视图就会正确调整大小以适应新的大小类。使用layoutSubviews
方法也可以,但可能会给您的应用程序带来额外的处理压力。