Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is layoutIfNeeded used?

Tags:

ios

uikit

iphone

When and how is layoutIfNeeded used? I know that when we change the layout of a view, we can call setNeedsLayout to update the layout but not sure when layoutIfNeeded should be used.

NOTE: I have layoutIfNeeded used in actual code but forgot in what context it was used.

like image 954
Boon Avatar asked Jul 25 '09 20:07

Boon


People also ask

Should I call layoutIfNeeded?

You should not call this method directly. If you want to force a layout update, call the setNeedsLayout() method instead to do so prior to the next drawing update. If you want to update the layout of your views immediately, call the layoutIfNeeded() method.

When should I use layoutSubviews?

layoutSubviews() The system calls this method whenever it needs to recalculate the frames of views, so you should override it when you want to set frames and specify positioning and sizing. However, you should never call this explicitly when your view hierarchy requires a layout refresh.

What is setNeedsLayout?

setNeedsLayout()Invalidates the current layout of the receiver and triggers a layout update during the next update cycle.


2 Answers

layoutIfNeeded forces the receiver to layout its subviews immediately if required.

Suppose you have overridden layoutSubviews, and UIKit feels that your view requires layout for whatever reason (e.g. you called setNeedsLayout when handling some user action). Then, your custom layoutSubviews method will be called immediately instead of when it would normally be called in the regular UIKit run loop event sequence (after event handling, but before drawRect:).

An example of why you might need to call layoutIfNeeded within a single run loop:

  1. You resize a custom view containing a table view with a custom layout. setNeedsLayout is set so that layoutSubviews will be called later.
  2. A controller object asks the table view to scroll to some particular cell when handling a user event.
  3. Your custom view performs some custom sizing of the table view in layoutSubviews that changes the table view size.

The problem is when the controller asked the table view to scroll (step 2), the table view had bounds that were stale. The updated bounds would only be set on the table view later (step 3). What the controller wanted the table view to scroll to may not actually be visible after layoutSubviews is done. A solution then would be for the controller to call layoutIfNeeded in situations where it knows this might occur.

like image 190
Allen Ding Avatar answered Oct 06 '22 00:10

Allen Ding


The difference between these two methods can be now be described by referencing the update cycle.

The method setNeedsLayout for a UIView tells the system that you want it to layout and redraw that view and all of its subviews, when it is time for the update cycle. This is an asynchronous activity, because the method completes and returns immediately, but it isn’t until some later time that the layout and redraw actually happens, and you don’t know when that update cycle will be.

In contrast, the method layoutIfNeeded is a synchronous call that tells the system you want a layout and redraw of a view and its subviews, and you want it done immediately without waiting for the update cycle. When the call to this method is complete, the layout has already been adjusted and drawn based on all changes that had been noted prior to the method call.

So, stated succinctly, layoutIfNeeded says update immediately please, whereas setNeedsLayout says please update but you can wait until the next update cycle.

like image 25
CrazyPro007 Avatar answered Oct 05 '22 23:10

CrazyPro007