web-dev-qa-db-ja.com

layoutIfNeededはどのように使用されますか?

layoutIfNeededはいつ、どのように使用されますか?ビューのレイアウトを変更すると、setNeedsLayoutを呼び出してレイアウトを更新できるが、layoutIfNeededをいつ使用するかはわからないことを知っています。

注:実際のコードではlayoutIfNeededが使用されていますが、使用されたコンテキストを忘れていました。

48
Boon

layoutIfNeededは、必要に応じてレシーバーにそのサブビューをすぐにレイアウトさせます。

layoutSubviewsをオーバーライドし、UIKitが何らかの理由でビューにレイアウトが必要だと感じたとします(たとえば、ユーザーアクションを処理するときにsetNeedsLayoutを呼び出しました)。その後、カスタムlayoutSubviewsメソッドは、通常のUIKit実行ループイベントシーケンスで通常呼び出されるのではなく、すぐに呼び出されます(イベント処理の後、drawRect:の前)。

単一の実行ループ内でlayoutIfNeededを呼び出す必要がある理由の例:

  1. カスタムレイアウトのテーブルビューを含むカスタムビューのサイズを変更します。 setNeedsLayoutは、layoutSubviewsが後で呼び出されるように設定されます。
  2. コントローラーオブジェクトは、ユーザーイベントを処理するときに、特定のセルにスクロールするようテーブルビューに要求します。
  3. カスタムビューは、テーブルビューのサイズを変更するlayoutSubviewsのテーブルビューのカスタムサイズ変更を実行します。

問題は、コントローラーがテーブルビューにスクロールするように要求したとき(ステップ2)、テーブルビューの境界が古いことです。更新された境界は、後でテーブルビューでのみ設定されます(ステップ3)。 layoutSubviewsが実行された後、コントローラーがテーブルビューにスクロールさせたいものが実際に表示されない場合があります。その場合の解決策は、コントローラーがlayoutIfNeededを呼び出すことで、これが発生する可能性があることがわかっている場合です。

65
Allen Ding

LayoutSubViews()-直接呼び出すのではなく、代わりにsetNeedsLayout()を呼び出します。制約ベースが予想される動作を提供しない場合はオーバーライドします。

SetNeedsLayout()-メインスレッドで呼び出し、次の描画サイクルを待ちます。パフォーマンスに適しています。

LayoutIfNeeded()-すぐにレイアウトのサブビュー。

0
Avijit Nagare

更新サイクルを参照することで、これら2つの方法の違いを説明できるようになりました。

UIViewのメソッドsetNeedsLayoutは、更新サイクルの時間になったときに、そのビューとそのすべてのサブビューをレイアウトおよび再描画するようにシステムに指示します。メソッドは完了してすぐに戻るため、これは非同期アクティビティですが、レイアウトと再描画が実際に行われるのは後ほどであり、その更新サイクルがいつになるかはわかりません。

対照的に、メソッドlayoutIfNeededは、システムにビューとそのサブビューのレイアウトと再描画を指示し、更新サイクルを待たずにすぐにそれを行うことをシステムに伝える同期呼び出しです。このメソッドの呼び出しが完了すると、メソッド呼び出しの前に記録されたすべての変更に基づいてレイアウトが既に調整および描画されています。

したがって、簡潔に言うと、layoutIfNeededはすぐに更新してください、setNeedsLayoutは更新してくださいと言っていますが、次の更新サイクルまで待つことができます。

0
CrazyPro007