我知道自动布局链基本上由 3 个不同的过程组成。
- 更新约束
- 布局视图(这是我们计算帧的地方)
- display
我不完全清楚的是两者之间的内在区别-setNeedsLayout
and -setNeedsUpdateConstraints
。来自苹果文档:
设置需求布局
当您需要时,可以在应用程序的主线程上调用此方法
调整视图子视图的布局。该方法记录了
请求并立即返回。因为该方法不
强制立即更新,但等待下一次更新
循环,你可以用它来使多个视图的布局失效
在更新任何这些视图之前。此行为使您能够
将所有布局更新合并到一个更新周期,即
通常更有利于性能。
设置需求更新约束
当自定义视图的属性发生变化时会影响
约束,可以调用该方法来表明约束
需要在将来的某个时候进行更新。然后系统将
调用 updateConstraints 作为其正常布局过程的一部分。更新中
在需要约束之前立即全部约束确保您
当进行多个更改时,不要不必要地重新计算约束
在布局过程之间对您的视图进行调整。
当我想在修改约束后对视图进行动画处理并对更改进行动画处理时,我通常会调用以下命令:
[UIView animateWithDuration:1.0f delay:0.0f usingSpringWithDamping:0.5f initialSpringVelocity:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
[self.modifConstrView setNeedsUpdateConstraints];
[self.modifConstrView layoutIfNeeded];
} completion:NULL];
我发现如果我使用-setNeedsLayout
代替-setNeedsUpdateConstraints
一切都按预期进行,但如果我改变-layoutIfNeeded
with -updateConstraintsIfNeeded
,动画不会发生。
我试图做出自己的结论:
-
-updateConstraintsIfNeeded
仅更新约束,但不强制布局进入该过程,因此仍保留原始帧
-
-setNeedsLayout
还打电话-updateContraints
method
那么什么时候可以使用其中一种而不是另一种呢?关于布局方法,我是否需要在约束发生更改的视图或父视图上调用它们?
你的结论是对的。基本方案是:
-
setNeedsUpdateConstraints
确保将来致电updateConstraintsIfNeeded
calls updateConstraints
.
-
setNeedsLayout
确保将来致电layoutIfNeeded
calls layoutSubviews
.
When layoutSubviews
被调用,它也调用updateConstraintsIfNeeded
,因此根据我的经验,很少需要手动调用它。事实上,除了调试布局时,我从未调用过它。
使用更新约束setNeedsUpdateConstraints
也是相当罕见的,objc.io——关于自动布局的必读——说:
如果稍后发生某些变化导致您的约束之一无效,您应该立即删除该约束并调用 setNeedsUpdateConstraints。事实上,这是您必须触发约束更新传递的唯一情况。
此外,根据我的经验,我从来没有必要使约束无效,也不必设置setNeedsLayout
在代码的下一行中,因为新的约束几乎要求新的布局。
经验法则是:
- 如果您直接操纵约束,请调用
setNeedsLayout
.
- 如果您更改了某些条件(例如偏移量或其他)would改变被覆盖的约束
updateConstraints
方法(更改约束的推荐方法,顺便说一句),调用setNeedsUpdateConstraints
,而且大多数时候,setNeedsLayout
在那之后。
- 如果您需要上述任何操作立即生效,例如当您需要在布局传递后学习新的框架高度时,请在其后附加
layoutIfNeeded
.
另外,在你的动画代码中,我相信setNeedsUpdateConstraints
是不需要的,因为约束是在动画之前手动更新的,并且动画仅根据新旧视图之间的差异重新布局视图。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)