layoutIfNeeded
はいつ、どのように使用されますか?ビューのレイアウトを変更すると、setNeedsLayout
を呼び出してレイアウトを更新できるが、layoutIfNeeded
をいつ使用するかはわからないことを知っています。
注:実際のコードではlayoutIfNeeded
が使用されていますが、使用されたコンテキストを忘れていました。
layoutIfNeeded
は、必要に応じてレシーバーにそのサブビューをすぐにレイアウトさせます。
layoutSubviews
をオーバーライドし、UIKitが何らかの理由でビューにレイアウトが必要だと感じたとします(たとえば、ユーザーアクションを処理するときにsetNeedsLayout
を呼び出しました)。その後、カスタムlayoutSubviews
メソッドは、通常のUIKit実行ループイベントシーケンスで通常呼び出されるのではなく、すぐに呼び出されます(イベント処理の後、drawRect:
の前)。
単一の実行ループ内でlayoutIfNeeded
を呼び出す必要がある理由の例:
setNeedsLayout
は、layoutSubviews
が後で呼び出されるように設定されます。layoutSubviews
のテーブルビューのカスタムサイズ変更を実行します。問題は、コントローラーがテーブルビューにスクロールするように要求したとき(ステップ2)、テーブルビューの境界が古いことです。更新された境界は、後でテーブルビューでのみ設定されます(ステップ3)。 layoutSubviews
が実行された後、コントローラーがテーブルビューにスクロールさせたいものが実際に表示されない場合があります。その場合の解決策は、コントローラーがlayoutIfNeeded
を呼び出すことで、これが発生する可能性があることがわかっている場合です。
LayoutSubViews()-直接呼び出すのではなく、代わりにsetNeedsLayout()を呼び出します。制約ベースが予想される動作を提供しない場合はオーバーライドします。
SetNeedsLayout()-メインスレッドで呼び出し、次の描画サイクルを待ちます。パフォーマンスに適しています。
LayoutIfNeeded()-すぐにレイアウトのサブビュー。
更新サイクルを参照することで、これら2つの方法の違いを説明できるようになりました。
UIViewのメソッドsetNeedsLayoutは、更新サイクルの時間になったときに、そのビューとそのすべてのサブビューをレイアウトおよび再描画するようにシステムに指示します。メソッドは完了してすぐに戻るため、これは非同期アクティビティですが、レイアウトと再描画が実際に行われるのは後ほどであり、その更新サイクルがいつになるかはわかりません。
対照的に、メソッドlayoutIfNeededは、システムにビューとそのサブビューのレイアウトと再描画を指示し、更新サイクルを待たずにすぐにそれを行うことをシステムに伝える同期呼び出しです。このメソッドの呼び出しが完了すると、メソッド呼び出しの前に記録されたすべての変更に基づいてレイアウトが既に調整および描画されています。
したがって、簡潔に言うと、layoutIfNeededはすぐに更新してください、setNeedsLayoutは更新してくださいと言っていますが、次の更新サイクルまで待つことができます。