何时调用layoutSubviews?
-
05-09-2019 - |
题
我有一个自定义视图没有得到 layoutSubview
动画期间的消息。
我有一个充满屏幕的视图。它在屏幕底部有一个自定义子视图,如果我更改导航栏的高度,它可以在 Interface Builder 中正确调整大小。 layoutSubviews
在创建视图时调用,但不会再调用。我的子视图布局正确。如果我关闭通话状态栏,子视图的 layoutSubviews
根本没有被调用,即使主视图确实对其大小进行了动画调整。
什么情况下是 layoutSubviews
真的打电话了?
我有 autoresizesSubviews
设置 NO
对于我的自定义视图。在 Interface Builder 中,我设置了顶部和底部支柱以及垂直箭头。
难题的另一部分是窗口必须成为关键:
[window makeKeyAndVisible];
否则子视图不会自动调整大小。
解决方案 5
我跟踪的溶液降至界面生成器的坚持,弹簧不能对具有模拟屏幕元件接通(状态栏等)的图而改变。由于弹簧是关闭的主视图,该视图不能改变大小,因此将其全部被向下滚动时,在呼叫酒吧出现了。
车削模拟功能关闭,然后调整大小视图和正确设置弹簧导致发生动画和我的方法被调用。
调试这个额外的问题是,模拟器退出应用程序时,通话中状态通过菜单切换。退出应用程式=无调试器。
其他提示
我有一个类似的问题,但对答案(或我在网上找到的任何答案)不满意,所以我在实践中进行了尝试,这就是我得到的:
init
不会导致layoutSubviews
被称为(duh)addSubview:
原因layoutSubviews
被调用 正在添加的视图,它正在的视图 添加到(目标视图),并且所有 目标的子视图- 看法
setFrame
智能呼叫layoutSubviews
上 仅设置了框架的视图 如果帧的 size 参数为 不同 - 滚动uiscrollview原因
layoutSubviews
被召唤 scrollView 及其 superview - 旋转设备仅调用
layoutSubview
在父视图( 响应 viewControllers primary 查看) - 调整视图大小将调用
layoutSubviews
在其超级视图上
我的结果 - http://blog.logichigh.com/2011/03/16/when-does-layoutsubviews-get- Called/
在 @BadPirate 之前的回答的基础上,我进一步进行了实验,并提出了一些澄清/更正。我找到 layoutSubviews:
当且仅当以下情况时才会在视图上调用:
- 它自己的 界限 (不是框架)改变了。
- 其直接子视图之一的边界发生了变化。
- 子视图被添加到视图中或从视图中删除。
一些相关细节:
- 仅当新值不同时,才认为边界已更改, 包括不同的起源. 。特别注意这就是为什么
layoutSubviews:
每当 UIScrollView 滚动时就会调用,因为它通过更改其边界的原点来执行滚动。 - 如果大小发生变化,更改框架只会更改边界,因为这是传播到bounds属性的唯一内容。
- 尚未在视图层次结构中的视图边界的更改将导致调用
layoutSubviews:
当视图最终添加到视图层次结构中时. - 只是为了完整性:这些触发器不 直接地 调用layoutSubviews,而是调用
setNeedsLayout
, ,设置/升起一个标志。对于所有视图,运行循环的每次迭代 在视图层次结构中, ,该标志被检查。对于发现旗帜升起的每个视图,layoutSubviews:
被调用并且标志被重置。将首先检查/调用层次结构中较高的视图。
每当以下任何事件发生在视图中时,都会发生布局更改:
A。视图边界矩形的大小发生变化。
b.界面方向发生变化,通常会触发根视图边界矩形的变化。
C。与视图层关联的核心动画子层集会发生变化并需要布局。
d.您的应用程序通过调用强制布局发生setNeedsLayout
或者layoutIfNeeded
视图的方法。
e.您的应用程序通过调用强制布局setNeedsLayout
视图底层对象的方法。
中的一些点 坏海盗的回答 仅部分正确:
为了
addSubView
观点addSubview
导致在要添加的视图、要添加到的视图(目标视图)以及目标的所有子视图上调用layoutSubviews。它取决于视图(目标视图)的自动调整大小蒙版。如果它打开了自动调整大小掩码,则将在每次调用layoutSubview
addSubview
. 。如果它没有自动调整大小掩码,则仅当视图(目标视图)帧大小更改时才会调用layoutSubview。例子:如果您以编程方式创建 UIView(默认情况下它没有自动调整大小掩码),则仅当 UIView 框架更改时才会调用 LayoutSubview,而不是每次更改时都会调用 LayoutSubview
addSubview
.通过这种技术,应用程序的性能也得到了提高。
对于设备旋转点
旋转设备仅调用父视图(响应viewController的主视图)上的layoutSubview
仅当您的 VC 位于 VC 层次结构中(根位于
window.rootViewController
),这是最常见的情况。在 iOS 5 中,如果您创建了一个 VC,但没有将其添加到任何其他 VC 中,那么当设备旋转时,该 VC 不会得到任何通知。因此它的视图不会通过调用layoutSubviews而被注意到。
主叫
[self.view setNeedsLayout];
在的viewController使得调用viewDidLayoutSubviews
有你看着layoutIfNeeded?
的文档片段是以下。难道动画工作,如果你在动画过程中显式调用此方法?
layoutIfNeeded 如果需要的话,勾画出子视图。
- (void)layoutIfNeeded
讨论 使用此方法来强制子视图的配置图之前。
状况 可用于iPhone OS 2.0和更新版本。
当从迁移SDK 3一个OpenGL应用4,layoutSubviews物不再被调用。大量的试验和错误我终于打开MainWindow.xib文件后,选择Window对象,在检查选择窗口属性选项卡(最左边),并检查“可见在启动”。看来,在SDK 3仍用来使layoutSubViews呼叫,但不是在4
6小时挫折的放结束。
当layoutSubviews
永远不会被称为A相当模糊,但可能是重要的情形是:
import UIKit
class View: UIView {
override class var layerClass: AnyClass { return Layer.self }
class Layer: CALayer {
override func layoutSublayers() {
// if we don't call super.layoutSublayers()...
print(type(of: self), #function)
}
}
override func layoutSubviews() {
// ... this method never gets called by the OS!
print(type(of: self), #function)
}
}
let view = View(frame: CGRect(x: 0, y: 0, width: 100, height: 100))