多くのiOS開発者は、Auto Layout'eで要素をレンダリングし、制約を設定および更新するメカニズムがどのように機能するかについて考えていません。この記事では、レイアウトエンジンの内部を詳しく見ていきます。
レイアウトパス
のレイアウトを渡す-これは、自動レイアウトエンジンが概念の階層をバイパスする場所ですが、すべてのviewControllerでViewWillLayoutSubviewsメソッドを、すべてのビューでlayoutSubviewsメソッドを発生させます。layoutSubviewsメソッドは、各サブビューのFrameプロパティを更新します
制約を追加、変更、または削除しても、すぐには更新されません。レイアウトを再計算し、変更のたびにレンダリングを更新するのは非効率的です。代わりに、変更は、ウィンドウが所有するレイアウトメカニズムをスケジュールして、実行ループの次の機会にレイアウトの更新をトリガーします。
一般的なレイアウトサイクルは、いくつかの段階で構成されています。
トリガー:レイアウトエンジンの入力を変更しています。これには、サブビューの追加または削除、内部コンテンツサイズの変更、制約のアクティブ化/非アクティブ化、優先度または定数制約の変更などがあります。
Update Model: layout engine view , views. the layout engine view.
. Views, , setNeedsLayout() superview, layout pass runloop.
Deferred Layout Pass: the layout pass view hierarchy. constraints. , , layoutSubviews() view, subviews, , views .
, viewController, view layout engine :
layout engine updateViewConstraints, view updateConstraints.
the layout pass layout engine viewWillLayoutSubviews viewDidLayoutSubviews , layoutSubviews layout
Constraints
view hierarchy , constraint' , layout engine views. updateConstraintsIfNeeded view, constraints. view, constraints, layout engine updateConstraints, . setNeedsUpdateConstraints, . , the layout engine , updateConstraintsIfNeeded.
Views
- view. the layout engine view frames .
, layout, layoutSubviews () subviews layout engine.
setNeedsLayout layoutIfNeeded, layout pass view. , layout pass view :
setNeedsLayout: layout. layout view layout pass application run loop.
layoutIfNeeded: layoutSubviews , , layout engine subviews
:
, constraints . the layout engine , .
. constraints. view layout, , the layout engine.
setNeedsLayout, layout'a. layoutIfNeeded view frames .