What is the difference between all these Auto Layout update methods? Are all necessary?

前端 未结 1 1516
野趣味
野趣味 2020-12-22 20:00

In the code below, these four methods are called for layout reasoning. I\'m a little confused why all of them are needed, though, and what they do differently from one anoth

1条回答
  •  时光说笑
    2020-12-22 20:12

    Layout

    Suppose you encapsulate your view logic in a UIView subclass, and call it SomeView. This means that SomeView should know how to layout itself, that is, how to position some other views inside it (you can also create a view that draws itself without using any subviews, but that's beyond the needs of an average developer).

    This layout is done by [SomeView layoutSubviews]. You have an option of overriding it:

    subview.frame = CGRectMake(100 + shiftX, 50 + shiftY, 250 + shiftX - paddingRight, ...
    // Oh no, I think I didn't do it right.
    

    but you rarely need to do so. In the dark ages of Cocoa Touch, this manual layout was widespread, but now I'd say 99% of layouts can be covered with Auto Layout.

    The system needs to know when it should call [UIView layoutSubviews]. It's obviously done the first time you need to draw a view, but it may be also called whenever the superview frame changes. Here's a detailed explanation.

    So the system often calls [view layoutIfNeeded]. You can also call it at any time, but this will have an effect only if there is some event that has called [view setNeedsLayout] or if you have called it manually, as in this case.

    Constraints

    The Auto Layout (capitalized this way in the documentation) is called like that because you're leaving [SomeView layoutSubviews] as it is inherited from UIView and describe the position of your subviews instead in terms of constraints.

    When using Auto Layout, system will perform calls to [view updateConstraintsIfNeeded] at each layout pass. However, only if the flag [view setNeedsUpdateConstraints]; is set, the method calls into -updateConstraints (which does the real job).

    If you don't use Auto Layout, those methods are not relevant.

    You can implement it like in this example.

    Your example

    It's rarely necessary to call -layoutIfNeeded and -updateConstraintsIfNeeded directly, because UI engine will do that automatically at each layout pass. However, in this case the author has chosen to call them immediately; this is because the resulting height is needed right now, not at some point in the future.

    This method of updating the cell's height seems right. Note that cell could be a newly created cell and thus not added into view hierarchy yet; this does not impact its ability to layout itself.

    Conclusion

    In your custom view go with the following options, starting from the most 'universal' to most 'customized':

    1. Create constraints during view creation (manually or in the IB)
    2. If you need to change the constraints later, override -updateConstraints.
    3. If have a complex layout that cannot be described by above means, override -layoutSubviews.

    In the code that changes something that could make your view's constraints change, call

    [view setNeedsUpdateConstraints];
    

    If you need results immediately, call also

    [view updateConstraintsIfNeeded]; 
    

    If the code changes view's frame use

    [view setNeedsLayout]; 
    

    and finally if you want the results immediately, call

    [view layoutIfNeeded];
    

    This is why all four calls are required in this case.

    Additional materials

    Take a look at detailed explanation in the article Advanced Auto Layout Toolbox, objc.io issue #3

    0 讨论(0)
提交回复
热议问题