关于 Xcode8中 autolayout 约束作用时间问题
关于 awakeFromNib
awakeFromNib 是继承自 NSObject
这个方法是用来提供把 nib 文件加载到 application 中的,但是 nib 文件中添加的约束是什么时候生效的呢?
在 vc 的 viewDidLoad
调用之前,会先调用添加到 vc.view的子 View 的 awakeFromNib
方法(如果是从 nib 加载)
layoutSubViews
从文档里可以看到,在 iOS5.1之前,这个方法does nothing,
否则,我们可以重写layoutSubViews中的约束来确定任何 subViews,不要直接调用,可以下一次视图更新之前调用 setNeedsLayout,如果想立即更新,调用 layoutIfNeeded.
view 的 layoutSubViews 被调用的情况:
1.addSubView
2.frame 发生改变
3.滑动 UIScrollView
4.旋转 Screen
5.改变 view的 subview 的 frame
6.调用 setLayoutSubViews
setNeedsLayout
标记为需要重新布局,异步调用 layoutIfNeeded,
在下一次 重新布局update cycle 之前调用 ,在主线程调用,因为 UIKit 下面的都不是线程安全的
layoutIfNeeded
立即刷新 UI
viewDidLayoutSubviews
当 vc.view的 bounds发生变化的时候,比如旋转。view会调整 subviews 的 position,然后系统会调用这个方法。
storyBoard 中约束作用时间问题
先在 storyBoard 的 vc.view 中添加一个 viewA,我试着在 VC 的 awakeFromNib
里面打印在viewA,为nil,如果对 viewA 发送消息也是无效的,因为 viewA 为 nil。但是 vc.view 的信息能打印出来,vc.view 的约束是正确的.那么在 storyBoard 中的 vc.view 上添加的子 View 是什么时候创建的?
在viewDidLoad
方法中打印 viewA,如果 storyBoard 中 viewA 存在misplaced,viewA
打印出来的是viewA:<UIView: 0x7fd8595055e0; frame = (67 253; 240 128); autoresize = RM+BM; layer = <CALayer: 0x60800003ecc0>>
,但是如果updateFrames
之后,打印的是viewA:<UIView: 0x7feab1608610; frame = (0 0; 1000 1000); autoresize = RM+BM; layer = <CALayer: 0x608000035140>>
,所以一旦把 viewA updateFrames
,约束的作用时间就延后了,在 ViewDidLoad
之后??
我又试着在 storyBoard 的 vc.view中添加了一个 子 view:viewB,在viewDidLoad
中手动添加约束,发现是能获取到 viewA 的约束的,说明在storyBoard更新约束后, viewA 的约束作用时间确实延后了
[UINib instantiateWithOwner:options:]
方法会调用[ViewController awakeFromNib]
,
VC 的awakeFromNib
会调用 nib 文件里面 vc 的view 的子 View,然后 VC awakeFromNib
然后[UIViewController loadViewIfRequired]
会调用[ViewController viewDidLoad]
方法,