首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在layoutIfNeeded()之后调用setNeedsLayout()

在layoutIfNeeded()之后调用setNeedsLayout()
EN

Stack Overflow用户
提问于 2022-09-30 04:33:05
回答 1查看 98关注 0票数 0

我和同事们讨论了setNeedsLayout()layoutIfNeeded()

从结论开始,我的同事说setNeedsLayout()‘可能’或‘应该’在layoutIfNeeded()之前被调用,因为如果我们不通过调用setNeedsLayout()将‘布局标志’设置为true,layoutIfNeeded()可能不会执行布局。然而,我的想法是,在同一个地方调用他们将导致相同的结果,我们只叫layoutIfNeeded()。因为..。

我所知道的是,正如这里这里所描述的,setNeedsLayout()只是使当前的布局无效,接下来的更新周期将处理剩下的部分。layoutIfNeeed()正在立即更新布局,因此不希望进入下一个更新周期。

简单地说,异步调用和同步调用。就是这样。

如果没有动画,我不记得我见过很多我不得不使用layoutIfNeeded的案例(可能有一两个)。大多数情况下,它只在setNeedsLayout()中运行得很好。此外,如果有一种情况需要在同一个地方调用它们,我宁愿说这是来自UIKit的一个bug。

有人能解释一下哪一个是正确的吗?为什么?

EN

回答 1

Stack Overflow用户

发布于 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()“等待”直到发生为止(这不是实际发生的情况,而是从某种角度来看,这是可以观察到的效果)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73904042

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档