可以在viewDidLoad中使用layoutIfNeeded来确定角半径大小吗?

时间:2016-09-27 16:58:37

标签: ios objective-c cocoa-touch uiviewcontroller

在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中正常工作。

3 个答案:

答案 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)

我认为更好的方法是在viewWillAppearviewDidLayoutSubviews

中执行此操作

那些是框架实际完成的时间。 viewDidLayoutSubviews很好,因为它会对视图框架中的更改做出反应。

答案 2 :(得分:2)

如果您要求针对不同尺寸类别使用不同的cornerRadius值,我会使用traitCollectionDidChange代替viewWillLayoutSubviewsviewDidLayoutSubviews

仅当iOS界面环境发生变化时才会调用

override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?)。如果首次加载视图,则previousTraitCollection将为nil

这样,如果您的应用程序支持多任务处理,只要视图大小更改为同时在您的设备屏幕上显示两个应用程序,您的视图就会正确调整大小以适应新的大小类。使用layoutSubviews方法也可以,但可能会给您的应用程序带来额外的处理压力。