auto layout に本当に夢中になっていることが1つあります。テストを行っているところ、UIView をサブクラス化し、いくつかのビューを制約付きで配置すると、計算された値を知ることが不可能であることがわかりました。
から継承する TestViewClass があるとは言いませUIView
ん。内部にいくつかのサブビューがあります。iPhone と iPad で使用したいので、2 つのサイズで使用します。たとえば、100x100 と 200x200 を使用して、すべてが機能するように制約を設定したとします。これらのサブビューをいくつかの位置に配置して、このビューを構築します。
ここで、実行時に指定されるサブビュー (contentView) としていくつかのボタンを含む別のサブビューを作成する必要があります。
アルゴリズムは、このコンテンツ ビューのサイズを選択し、互いに同じ距離にあるがコンテンツ ビューの幅全体をカバーするように、ボタン間のスペースを計算して正しい数のボタンを配置します。たとえば、contentView の幅は 200 ポイントで、ボタンは 3 で、1 辺が 60 の正方形です。これらを合わせて 180 をカバーするため、ボタン間のスペースとして配置する必要がある 20 ポイントが残っています -> 10 ポイント。
これは非常に簡単で、自動レイアウトの前に何千回も作成されています。そのためには、スーパービューのサイズに応じて幅のサイズを変更するスーパービューにいくつかの制約がある contentView の幅が必要です。問題は、 UIView 実装内で最終値を取得できる場所が見つからないことですcontentView のサイズ。
眺めてみた-layoutSubviews
、-updateConstraints
、-didMoveToSuperview
、値の表示は常に元のものです。新しいフレームはいつ計算されますか?
自動レイアウトについては明らかに何もわかりませんでした...
テーブルビューのセルの高さを設定しようとして、テーブルビューのサイズによってすべてを個別に画面に表示しようとして、この問題を発見しました。ここに関連する質問があります他の質問
2 に答える
viewDidLayoutSubviews
ビューがレイアウトされたときに通知するビューコントローラーの を使用できます。このすべてがカスタムUIView
で発生している制約の追加である場合は、ビューの呼び出しメソッドを記述しviewDidLayoutSubviews
、ビュー コントローラーがそれを受け取ったときにそれをビュー コントローラーに呼び出すことができます。この時点で、コンテナーの寸法が適切に構成されている必要があります。
ただし、コンテナー ビューのサイズを気にせずにボタンの束を均等に配置する方法がいくつかあります。
コンテナー内のコントロールを均等に配置するために私が使用した 1 つのアプローチは、私が「スペーサー」ビュー (表示されているが
clearColor
背景だけであるため、視覚的には見えないビュー) と呼ぶものを作成することです。次に、次のようなものを効果的に使用して、一連の制約を作成できます。H:|[spacer1][button1(60)][spacer2(==spacer1)][button2(60)][spacer3(==spacer1)][button3(60)][spacer4(==spacer1)]|
ボタンの数が固定されている場合は、上記のように単一のでこれを行うことができます
constraintsWithVisualFormat
。ボタンの数が可変の場合は、ボタンとスペーサーのペアごとに VFL 文字列を作成して、それらを反復処理できます (たとえば、最初のボタンは次の VFL を使用します)。H:|[spacer][button(60)]
後続のものはすべて、別のボタンと別のスペーサーを作成し、次の VFL を使用します。
H:[previousButton][spacer(==originalSpacer)][button(60)]
そして、最後に最後のスペーサーを 1 つ追加します。
H:[lastButton][spacer(==originalSpacer)]|
これは少し面倒ですが、ご覧のとおり、コントロールは完全に配置され、等間隔に配置されており、コンテナーの寸法を知る必要はありません。
もう 1 つの方法は
NSLayoutFormatAlignAllCenterX
、, 属性を使用することです。これにより、これらすべてのスペーサーを作成する必要がなくなりますが、以下で行うような単純なアルゴリズムを使用すると、中心がそれらの間で均等に分散されます。したがって、ボタンの標準の垂直方向の制約と水平方向の幅の制約に加えて、ボタンの水平方向の配置を次の方法で制御できます。[containerView addConstraint:[NSLayoutConstraint constraintWithItem:button[i] attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:containerView attribute:NSLayoutAttributeCenterX multiplier:2.0 * (double) (i + 0.5) / (double) n constant:0.0]];
は
i
、この水平方向の制約を設定するボタンの 0 から始まるインデックスで、n
ボタンの数です。