本文介绍了UIView 的 setNeedsLayout、layoutIfNeeded 和 layoutSubviews 是什么关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁能对UIView 的 setNeedsLayoutlayoutIfNeededlayoutSubviews 方法之间的关系给出明确的解释?以及将使用所有三个的示例实现.谢谢.

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 是什么关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 09:40