My understanding is, after execute setNeedsLayout
will mark the view as "dirty" so that in the next rendering cycle, the view will be be re-layout. layoutIfNeeded
will force to trigger re-layout immediately if the view is marked as "dirty".
However, even layoutIfNeeded
immediately start to layout, it does not mean that the code after layoutIfNeeded
will be waiting until it finishes. The render part is an async operation, it will be handled by core graphic through runloop.
myView.setNeedsLayout()
myView.layoutIfneeded()
print(myView.frame)
My point is, the printing of frame above may not always get correct frame, since the render operation is an async task, am I right?
Some context:
am I right
Yes. If you want the frame right now, either flush the current transaction or (perhaps better) allow a cycle by doing a zero-delay asyncAfter
. See How to, simply, wait for any layout in iOS? (and probably I should just be closing this question as a dupe of that one).
I should mention that an even better way is just to implement viewDidLayoutSubviews
or layoutSubviews
. That way, you arrive into the layout cycle at exactly the right moment to obtain any desired frame info.