3

この属性を使用する場合NSLayoutAttributeCenterX、乗数が 1 の場合、参照されたビューと一致する中心になります。値を増やすと左に移動し、0 に向かって減らすと右に移動します。

2.5、1、および 0.625 の乗数を使用して、試行錯誤 (スーパー ビュー全体に均等に配置された 3 つのビュー) によって、おおまかな結果を得ることができました。いじり回しているうちに、参照されたビューの左端の中央に 200 が配置され (それ以上に増加してもビューは移動しません)、0.5 が右端の中央に配置されていることがわかりました (0 に向かって減少すると、ビューがさらに左に移動します)。 .

可視化のためのクイックホワイトボード

だからここに私の質問があります:

  1. これは何ですか?
  2. このようにビューを正確に配置するために使用できる式はありますか、それとも試行錯誤が永遠に続きますか?
  3. なぜ彼らはこれをするのですか?
4

2 に答える 2

10

乗数が 1.0 でない場合、中心の制約が何を意味するのかを理解するのは難しいです。私は Xcode 6 でいくつかの実験を行いましたが、これが私の結論です。

問題の制約の形式A.center.x = B.center.x * m + cは です。ABは関係するビュー、mは制約の乗数、cは制約の定数です。

center.xBが他の制約によって固定されていると仮定しましょう。次に、自動レイアウトがこのアルゴリズムを使用したかのように動作すると思います。

  1. A と B の最も近い共通の祖先ビューを見つけます。この共通の祖先を G と呼びます。

  2. G の座標系で bxg = Bxcenter とします。としてコードでこれを計算できますCGFloat bxg = [G convertPoint:B.center fromView:B.superview].x

  3. axg = G の座標系における A の希望する x 中心を計算します。 CGFloat axg = bxg * m + c.

  4. axg を の座標系に変換し、A.superviewとして保存しA.center.xます。

では、「等間隔のビュー」という目標を達成するために、中心の制約をどのように使用すればよいでしょうか? 私たちはしません。

これが問題です。3 つのサブビューがすべて同じ幅 w であるとします。(幅が異なる場合、問題はさらに難しくなります。) そして、コンテナー ビューの幅が W であるとしましょう。中央のサブビューと右側のサブビュー、右側のサブビューの右側に 1 つ)。

したがって、余白の幅は (W - 3 w) / 4 となるはずです。次に、それを何らかの形で別の制約に差し込みます。中央の制約を使用したかったのですが、簡単にするために、左端のビュー L の左端の制約を考えてみましょう。制約を L.left = (W - 3 w) / 4 にする必要があります。この制約は複雑すぎます。直接処理する autolayout。自動レイアウトの制約には 2 つのビュー属性しか関与できませんが、これには 3 つの属性が関与します。

解決策は、スペーサー ビューを導入することです。必要な 3 つのサブビューから始めましょう。

開始ビュー

これら 3 つのサブビューのそれぞれを 80x80 で垂直方向の中央揃えに既に制約しています。

ここで、灰色で示されている 4 つのスペーサー ビューを追加します。

追加されたスペーサー ビュー

各スペーサーの高さと垂直方向の中心を制限しましたが、幅は制限していません。次に行うことは、すべてのスペーサーが同じ幅になるように制約することです。

等幅

次に、各スペーサーのリーディング エッジとトレーリング エッジを最も近い隣接するエッジに固定し、手動で定数をゼロに設定します。最初のスペーサーの作り方は次のとおりです。

スペーサーエッジ

他の 3 つのスペーサーについても同じことを行います。ここではそれを示しません。

ビュー コントローラーを選択し、Xcode にすべてのフレームを更新するように依頼すると、等間隔のビューが表示されます。

フレームを更新する

実際には実行時にスペーサーを表示したくないので、スペーサーを選択して非表示に設定します。 非表示のビューは引き続きレイアウトに参加します。

スペーサーを隠す

では、サブビューの幅がすべて同じでない場合はどうなるでしょうか? 青いサブビューの幅を変更しましょう:

青いサブビューの幅を変更

自動レイアウトは、スペーサーが引き続き同じ幅になるようにフレームを更新します。

于 2014-09-19T22:21:51.873 に答える