我已经阅读了一些文章,说明setNeedsLayout和layoutIfNeeded之间有什么区别,而我关注的是:
1。如果我想立即布局,我是否需要将这两种方法一起调用,因为我多次看到这种组合
2。我什么时候需要调用setNeedsLayout?根据我的理解,如果我更改视图的框架,它将在下一个周期更新布局,我不必显式调用setNeedsLayout
答案 0 :(得分:3)
这些工作如何工作是通过失效来删除冗余。如果需要布局,视图将包含信息。
因此调用setNeedsLayout
只会将一些内部布尔值needsLayout
设置为true
。调用layoutIfNeeded
后,它将检查此布尔值
if needsLayout {
needsLayout = false
doMagic() // Calls layoutSubviews at some point
}
为什么设计这种方式是因为多次调用可能会使布局无效,但我们只希望将其布局一次或尽可能少的布局。
在大多数情况下,您无需致电setNeedsLayout
,因为大多数更改已经为您执行了此操作。例如,您可以更改约束值并为您完成失效。您只需致电layoutIfNeeded
,您的观点就会更新。为了更加正确,您甚至不需要拨打layoutIfNeeded
,因为它会在下一个周期为您执行此操作。但是如果你想让动画更改动画,你需要调用它,你需要在动画块中做到这一点。
myViewConstraint.constant = 40.0 // Will already call setNeedsLayout
UIView.animate(withDuration: 0.3, animations: {
myView.layoutIfNeeded()
})
因此,更改约束只会改变有关视图应如何布局的信息。只有对layoutIfNeeded
的调用才会实际使用这些值并更改布局。这就是为什么你只需要把它放在动画块中(尽管把它全部放在块中也没错)。
公平地说,现在默认情况下会有一些变化(你可以禁用它)动画方法已经自己布局你的视图,所以你可以用更少的代码来做,但这不是现在的重点。
所以:
您无需一起调用2个方法即可进行布局。如果视图布局已经失效(在大多数情况下是这样),那么layoutIfNeeded
就足够了。但请注意setNeedsLayout
与将内部布尔值设置为true一样简单,因此调用它没有任何害处,只是一种预防措施。所以调用两者都更安全。单独拨打setNeedsLayout
将不会做任何事情"立即"虽然。
希望您永远不需要致电setNeedsLayout
。在某些复杂的情况下,您需要显式地使布局无效,并且存在一些可能的UI错误。在所有其他情况下,这将为您完成。但请注意,如果您遇到需要调用此情况的情况,它将在下一个周期更新布局"不会是真的。在视图布局无效之前,它根本不会布局。
我不确定setNeedDisplay
在你的问题中的位置(仅在你的标题中),但这个方法的工作方式相同,但有点复杂。它会使其内容无效并强制重绘,请致电drawRect
。这必须在其绘制管道中发生,而不是随时发生,因此您可能不会显式调用它来重绘。如果你什么都不做就会发生(也许会崩溃),因为它没有任何上下文可供使用。如果您覆盖drawRect
并调整视图大小,则会尝试缓存您绘制的内容并使用contentMode
调整图形大小。默认情况下,它设置为scaleToFill
,这意味着您的内容将随着视图大小的变化而延长。您需要致电setNeedDisplay
,以便再次调用drawRect
,然后您可以相应地重新绘制内容。
答案 1 :(得分:0)
我找到了我想问的问题,什么时候应该调用setNeedLayout,什么时候不应该。因为调用setNeedLayout的目的是调用layoutSubviews,所以对于以下情况,我不必调用setNeedLayout