ios - 为什么-setNeedsLayout -layoutsubviews方法之后立即执行

标签 ios autolayout

据我所知,-setNeedsLayout方法仅向 View 设置标志,以便在下一个更新周期布局 subview 。但是layoutIfNeeded会立即调用layoutSubviews方法,而不是等待下一个更新周期。

但是当我在 View 上调用 -setNeedsLayout 时,-layoutSubviews 方法会立即执行。据我了解,下一个更新周期应该仅在用户交互或 View 的框架更改时运行。我有什么地方说错了吗?也许 setNeedsLayout 调用更新周期?但当?它将如何运作?例如,如果我调用 3 个方法

[self setNeedsLayout];
[self setNeedsUpdateConstraints];
[self setNeedsDisplay];

最佳答案

我终于找到答案了。 感谢warren-burton ,分享一下 WWDC 演示的链接,真的很有帮助。

要回答我的问题,我们首先应该了解什么是“更新周期”。它由三部分组成。约束部分(更新所有约束),布局部分(设置所有框架)和绘图部分(在屏幕上绘制 View )。我的问题被误解的主要原因是我不知道

更新周期是一个循环

该循环始终运行。这意味着潜在的更新周期每秒可以运行大约 120 次。如果我们每秒更新约束、布局和重绘 120 次,那性能真的很差。为了避免这个问题,有一个标志来更新布局、更新约束和绘图。因此,每个更新周期系统都会检查每个部分是否需要调用相应的方法。 updateConstraints()layoutSubviews()drawRect() 等方法仅在相应标志打开时调用。

我们可以影响这些标志吗?

是的,我们可以通过setNeedsUpdateConstraints()setNeedsLayout()setNeedsDisplay()方法将needed标志设置为true。因此,如果我们调用 setNeedsLayout() 方法,该标志将设置为 true,并且布局将在下一个更新周期中更新。

enter image description here

为什么在setNeedsLayout layoutsSubviews方法之后立即执行

它永远不会立即执行。仅在用户看来,更新周期在调用 setNeedsLayout 后立即运行,因为更新周期运行得非常快且频繁。 需要理解的一个很好的例子是不断变化的约束常数。

print(label.frame.height) // 100
labelHeightConstraint.constant = 200
print(label.frame.height) // 100

更改约束后,系统会重新计算帧并调用setNeedsLayout()在下一个更新周期更新帧。如果打印帧的高度,它会是旧的,因为更新周期还没有发生。要查看计算出的帧,您应该通过 layoutIfNeeded() 方法立即强制调用该方法

print(label.frame.height) // 100
labelHeightConstraint.constant = 200
layoutIfNeeded()
print(label.frame.height) // 200

关于ios - 为什么-setNeedsLayout -layoutsubviews方法之后立即执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52899704/

相关文章:

ios - Swift - 为什么 ScrollView 不是全屏?

ios - uitextfield 动画宽度约束

c++ - 从音频文件转换ExtAudioFile时,ExtAudioFileGetProperty失败

iphone - UIGestureRecognizer 存储在 NSData 中

ios - 降低约束的优先级到底有什么作用?

ios - RTL(从右到左)通过自动布局在 iOS 6.1/iOS 7.0 上损坏?

ios - 设置自动布局约束后, subview 没有宽度或高度

ios - 变量 courseTitle 从未改变

ios - 使用单个 iOS 设备测试 iCloud 同步

objective-c - 包标识符应该是小写字母还是驼峰字母?