我和同事们讨论了setNeedsLayout()
和layoutIfNeeded()
。
从结论开始,我的同事说setNeedsLayout()
‘可能’或‘应该’在layoutIfNeeded()
之前被调用,因为如果我们不通过调用setNeedsLayout()
将‘布局标志’设置为true,layoutIfNeeded()
可能不会执行布局。然而,我的想法是,在同一个地方调用他们将导致相同的结果,我们只叫layoutIfNeeded()
。因为..。
我所知道的是,正如这里和这里所描述的,setNeedsLayout()
只是使当前的布局无效,接下来的更新周期将处理剩下的部分。layoutIfNeeed()
正在立即更新布局,因此不希望进入下一个更新周期。
简单地说,异步调用和同步调用。就是这样。
如果没有动画,我不记得我见过很多我不得不使用layoutIfNeeded
的案例(可能有一两个)。大多数情况下,它只在setNeedsLayout()
中运行得很好。此外,如果有一种情况需要在同一个地方调用它们,我宁愿说这是来自UIKit的一个bug。
有人能解释一下哪一个是正确的吗?为什么?
发布于 2022-09-30 06:47:49
首先,讨论一下这些方法是做什么的,你的问题的答案在下面。
来自setNeedsLayout()
的文档
此方法记录请求并立即返回。由于此方法不强制立即更新,而是等待下一个更新周期,因此可以使用它在更新任何这些视图之前使多个视图的布局失效。
通常,如果有一些外部因素影响UIKit不知道的布局(例如,通过重写layoutSubviews()的老式手动布局代码),则需要对其进行调用。它不会触发立即的重新布局,这通常只发生在下一个主运行循环迭代中。这允许您将多个视图标记为需要布局,您可以在同一个runloop迭代中多次在相同视图上调用它,但是UIKit只执行实际布局一次(正如我刚才提到的,通常在下一个runloop迭代中)。
但是,如果您需要立即解决布局问题(例如,因为需要度量其结果),则需要调用layoutIfNeeded()
。
如果没有未挂起的布局更新,则此方法将退出,而无需修改布局或调用任何与布局相关的回调。
这是layoutIfNeeded()
的一个关键点:如果布局系统不知道有挂起的更改,那么它根本不会做任何更改。调用setNeedsLayout()
是我们告诉布局系统有一些更改需要运行布局的方式。
如果您只使用自动布局并仅操作将要重新布局的视图的约束,您可以跳过setNeedsLayout()
,因为它已经被间接调用了;但是setNeedsLayout()
非常便宜,所以如果您不确定的话,调用它没有坏处。
那么,在调用setNeedsLayout()
之后,您需要调用layoutIfNeeded()
吗?要简单地更新屏幕上的视图,不需要调用layoutIfNeeded()
,因为UIKit将在下一个主要运行循环迭代中自己调用。事实上,如果您总是调用layoutIfNeeded()
,则可能会对呈现性能产生负面影响,即使您的代码不需要立即更新布局,因为这可能导致在同一个runloop迭代中多次布局运行。
但是,如果您立即依赖于布局信息(例如,您需要度量视图的高度),则需要调用它。只是要小心让你的设计不要做得太频繁。
您与“异步”和“同步”的比较确实有点贴切:在某种程度上,您可以将setNeedsLayout()
看作是触发异步操作,而layoutIfNeeded()
“等待”直到发生为止(这不是实际发生的情况,而是从某种角度来看,这是可以观察到的效果)。
https://stackoverflow.com/questions/73904042
复制相似问题