问题描述
谁能对UIView 的
setNeedsLayout
、layoutIfNeeded
和layoutSubviews
方法之间的关系给出明确的解释?以及将使用所有三个的示例实现.谢谢.
Can anyone give a definitive explanation on the relationship between UIView's
setNeedsLayout
, layoutIfNeeded
and layoutSubviews
methods? And an example implementation where all three would be used. Thanks.
让我感到困惑的是,如果我向我的自定义视图发送 setNeedsLayout
消息,那么它在此方法之后调用的下一件事是 layoutSubviews
,直接跳过 layoutIfNeeded
.从文档中,我希望流程是 setNeedsLayout
> 导致 layoutIfNeeded
被调用 > 导致 layoutSubviews
被调用.
What gets me confused is that if I send my custom view a setNeedsLayout
message the very next thing it invokes after this method is layoutSubviews
, skipping right over layoutIfNeeded
. From the docs I would expect the flow to be setNeedsLayout
> causes layoutIfNeeded
to be called > causes layoutSubviews
to be called.
推荐答案
我仍在尝试自己解决这个问题,所以请持怀疑态度,如果它包含错误,请原谅我.
I'm still trying to figure this out myself, so take this with some skepticism and forgive me if it contains errors.
setNeedsLayout
很简单:它只是在 UIView 的某处设置一个标志,将其标记为需要布局.这将强制在下一次重绘发生之前在视图上调用 layoutSubviews
.请注意,在许多情况下,您不需要显式调用它,因为 autoresizesSubviews
属性.如果已设置(默认情况下),则对视图框架的任何更改都将导致视图布局其子视图.
setNeedsLayout
is an easy one: it just sets a flag somewhere in the UIView that marks it as needing layout. That will force layoutSubviews
to be called on the view before the next redraw happens. Note that in many cases you don't need to call this explicitly, because of the autoresizesSubviews
property. If that's set (which it is by default) then any change to a view's frame will cause the view to lay out its subviews.
layoutSubviews
是你做所有有趣事情的方法.如果您愿意,它相当于用于布局的 drawRect
.一个简单的例子可能是:
layoutSubviews
is the method in which you do all the interesting stuff. It's the equivalent of drawRect
for layout, if you will. A trivial example might be:
-(void)layoutSubviews {
// Child's frame is always equal to our bounds inset by 8px
self.subview1.frame = CGRectInset(self.bounds, 8.0, 8.0);
// It seems likely that this is incorrect:
// [self.subview1 layoutSubviews];
// ... and this is correct:
[self.subview1 setNeedsLayout];
// but I don't claim to know definitively.
}
AFAIK layoutIfNeeded
通常不会在您的子类中被覆盖.当您希望立即布置视图时,您应该调用该方法.Apple 的实现可能如下所示:
AFAIK layoutIfNeeded
isn't generally meant to be overridden in your subclass. It's a method that you're meant to call when you want a view to be laid out right now. Apple's implementation might look something like this:
-(void)layoutIfNeeded {
if (self._needsLayout) {
UIView *sv = self.superview;
if (sv._needsLayout) {
[sv layoutIfNeeded];
} else {
[self layoutSubviews];
}
}
}
您可以在视图上调用 layoutIfNeeded
以强制立即对其(以及必要时的超视图)进行布局.
You would call layoutIfNeeded
on a view to force it (and its superviews as necessary) to be laid out immediately.
这篇关于UIView 的 setNeedsLayout、layoutIfNeeded 和 layoutSubviews 是什么关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!