28

UIView のいくつかのプロパティを変更すると、スーパービューlayoutSubviewsでトリガーされます。ドキュメントでこれに関する声明を見つけることができません。

これらのプロパティは、スーパービューとセルフでレイアウトをトリガーします

  • フレーム
  • 境界

これらのプロパティは、スーパービューでのみレイアウトをトリガーします

  • 変身
  • レイヤー変換

これらのプロパティは、自分自身でのみレイアウトをトリガーします

  • なし

これらのプロパティはレイアウトをトリガーしません

  • 中心
  • layer.anchorPoint
  • レイヤーの位置
  • アルファ

transform がレイアウトをトリガーし、その位置と anchorPoint がそうでないことは非常に混乱しています。

コード例: https://github.com/hfossli/LayoutSubviewsInconsistency


私は知りたいです:

  • なぜこの動作が見られるのか
  • これが本当に矛盾している場合、またはいくつかのコアコンセプトを誤解している場合
  • トランスフォームを変更するたびにスーパービューをレイアウトサブビューにしないようにする方法

これについては、ドキュメントにもヘッダー ファイルにも何も見つかりません。UIDynamics などを使用する場合、この問題は重大です。

4

1 に答える 1

31

AppleはTSI経由で私に答えました(個人的にはこれはゴミだと思います):

パート1

なぜこの動作が見られるのですか? これは矛盾していますか、それともいくつかのコアコンセプトを誤解していますか?

ビューがそのサブビューのフレームを再計算する必要がある何かが変更されたとシステムが感じたときはいつでも、ビューにレイアウトのフラグが立てられます。これは、予想よりも頻繁に発生する可能性があり、まさにシステムがレイア​​ウトを必要とするビューにフラグを立てることを選択したときに発生します。これは実装の詳細です。

ビュー階層を上にカスケードするのはなぜですか?

一般に、ビュー (またはレイヤー) のジオメトリ プロパティを変更すると、ビュー階層の上方にレイアウトの無効化が連鎖的に発生します。これは、親ビューが、変更された子を含む自動レイアウト制約を持っている可能性があるためです。自動レイアウトは、明示的に有効にしているかどうかに関係なく、何らかの形でアクティブになっていることに注意してください。

変換を変更するたびにスーパービューをレイアウトサブビューにしないようにするにはどうすればよいですか?

この動作を回避する方法はありません。これは、ビュー階層の一貫性を保つために必要な UIKit の内部簿記の一部です。

パート2

こんにちは。

しかし、これが本当なら、なぜこれが 'layer.anchorPoint' と 'center'/'layer.position' に当てはまらないのか理解できません。

この場合、私たちはより保守的である可能性があります。親ビューは、自動レイアウトが関与する場合を除いて、子の位置を気にする必要はありません。また、自動レイアウトが関係している場合は、制約を直接変更して、とにかく位置を永続的に調整する必要があります。

この変換は、再び上にカスケードする layoutSubviews をトリガーします。

変換への変更は、ビューの直接の親のレイアウトを無効にするだけであることを理解しています (変更されたビューに制約を設定しない限り、より複雑になります)。また、レイアウトの無効化はバッチ処理されるため、親のレイアウト サブビューのメソッドはトランザクション (フレーム) ごとに 1 回だけ呼び出す必要があります。それでも、レイアウト ロジックが複雑な場合、パフォーマンスの問題が発生する可能性があることは理解できます。

何か案は?

中間ビューでセルの内容をラップします。この中間ビューの変換を変更する場合、セルのレイアウトのみを無効にする必要があるため、高価なレイアウト メソッドは呼び出されません。

それが機能しない場合は、高価なレイアウト メソッドが実際に機能する (または機能しない) ときに通知するメカニズムを作成します。これは、変更がトランスフォームに対してのみ行われる場合に設定するプロパティである可能性があります。

于 2014-07-10T09:34:15.480 に答える