ios - setNeedsLayout 与 setNeedsUpdateConstraints 和

我知道自动布局链基本上包含 3 个不同的过程。

  1. 更新约束
  2. 布局 View (这里是我们计算帧的地方)
  3. 显示

我不太清楚-setNeedsLayout-setNeedsUpdateConstraints 之间的内在区别。来自 Apple 文档:

setNeedsLayout

Call this method on your application’s main thread when you want to adjust the layout of a view’s subviews. This method makes a note of the request and returns immediately. Because this method does not force an immediate update, but instead waits for the next update cycle, you can use it to invalidate the layout of multiple views before any of those views are updated. This behavior allows you to consolidate all of your layout updates to one update cycle, which is usually better for performance.

setNeedsUpdateConstraints

When a property of your custom view changes in a way that would impact constraints, you can call this method to indicate that the constraints need to be updated at some point in the future. The system will then call updateConstraints as part of its normal layout pass. Updating constraints all at once just before they are needed ensures that you don’t needlessly recalculate constraints when multiple changes are made to your view in between layout passes.

当我想在修改约束后为 View 设置动画并为我通常调用的更改设置动画时:

[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使用 -updateConstraintsIfNeeded,动画不会发生。
我试图做出自己的结论:

  • -updateConstraintsIfNeeded 只更新约束但不强制布局进入进程,因此仍保留原始帧
  • -setNeedsLayout 也调用 -updateContraints 方法

那么什么时候可以用一个代替另一个呢?关于布局方法,我需要在约束发生变化的 View 或父 View 上调用它们吗?

最佳答案

你的结论是对的。基本方案是:

  • setNeedsUpdateConstraints 确保将来对 updateConstraintsIfNeeded 的调用会调用 updateConstraints
  • setNeedsLayout 确保将来对 layoutIfNeeded 的调用调用 layoutSubviews

当调用 layoutSubviews 时,它也会调用 updateConstraintsIfNeeded,因此根据我的经验,很少需要手动调用它。事实上,除了调试布局时,我从未调用过它。

使用 setNeedsUpdateConstraints 更新约束也很少见,objc.io–a must read about autolayouts–says :

If something changes later on that invalidates one of your constraints, you should remove the constraint immediately and call setNeedsUpdateConstraints. In fact, that’s the only case where you should have to trigger a constraint update pass.

此外,根据我的经验,我从来不需要使约束无效,也不必在代码的下一行设置 setNeedsLayout,因为新的约束几乎要求新的布局。

经验法则是:

  • 如果您直接操作约束,请调用 setNeedsLayout
  • 如果您更改了某些条件(如偏移量或 smth) 更改覆盖的 updateConstraints 方法中的约束(顺便说一句,这是更改约束的推荐方法),请调用 setNeedsUpdateConstraints,大多数时候,setNeedsLayout 之后。
  • 如果您需要上述任何操作来立即生效,例如当您需要在布局传递后了解新的帧高度时 - 使用 layoutIfNeeded 附加它。

另外,在您的动画代码中,我相信 setNeedsUpdateConstraints 是不需要的,因为约束是在动画之前手动更新的,并且动画只会根据旧 View 和旧 View 之间的差异重新布局 View 新的。

关于ios - setNeedsLayout 与 setNeedsUpdateConstraints 和 layoutIfNeeded 与 updateConstraintsIfNeeded,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20609206/

相关文章:

ios - 如果模态 ViewController 演示样式为 UIModalPresentatio

objective-c - 如何检查 NSString 是否以某个字符开头

objective-c - 有没有办法从 UITableView 中删除分隔线?

ios - 查看保存的 NSUserDefaults 的简单方法?

ios - 如何以毫秒为单位准确记录方法的执行时间?

ios - 我可以强制 UITableView 隐藏空单元格之间的分隔符吗?

objective-c - GCD 在主线程中执行任务

objective-c - 在 Storyboard中,如何制作用于多个 Controller 的自

objective-c - registerForRemoteNotificationTypes :

ios - 使用 NSURLSession 发送 POST 请求