AutoLayoutの実装を開始し、カスタムUITableViewCell
クラスの1つを適切に接続する方法をつなぎ合わせようとしています。通常、標準の字幕クラスと同様に、2つのUILabel
オブジェクトが上下に重なります。セルの高さに関係なく、これら2つのラベルをセルの中央に配置し、2つの間に特定のパディングを配置したいと思います。
これは、2つのラベルの高さを加算し、パディングを加算してから、セルの高さから減算し、2で割るなどの方法で実行できると思います。ただし、これが正しいかどうかは意味的に興味があります。セルの上下からではなく、上下から制約するためです。私はここでトリックを逃していますか?
次に、3番目のラベルが積み重ねられていることもあるので、3つを重ねます。その場合、2セットのパディングなどが必要になりますが、質問はさらに関連性が高くなります。セルの上下ではなく、互いに制約するべきではないでしょうか。
したがって、質問はセマンティックなものです。親ビュー内で複数の要素を垂直方向に制約したい場合、上記で提案した方法よりも賢い方法はありますか?
(問題のセルにはXIBがなく、ストーリーボードにないため、現在、AutoLayoutを完全にコードで(Masonryを使用して)実装しています)。
正しいアプローチは、サブビューから高さを取得するコンテナビューを使用することです。次に、コンテナビューがセルの中央に固定されます。コンテナをセルの上端と下端にリンクする制約はありません。
コンテナ内では、垂直方向の制約は|[label1]-[label2]|
になります。これにより、コンテナは2つのラベルの高さとスペースになり、コンテナビューの中心は2つのラベルの間になります。
3つのラベルを追加した場合、それは|[label1]-[label2]-[label3]|
になり、コンテナーの中心は中央のラベルの中心になります。
いずれの場合も、コンテナの中心はセルの中心になり、何も計算する必要はありません。
Interface Builderを使用、次の手順を使用して、複数のUIViewを垂直方向に中央揃えにすることができます。私のユースケースは、これらの複数のUIViewを可能な限りグループのように動作させたいが、それを実現するためにこれ以上ビューを導入したくないというものです。
まず、下部にあるボタンを使用して、デフォルトのフォームファクターと見なすものを選択します(フォームファクターは3.5インチまたは4インチの網膜です)。次に、ボタンを1つずつドラッグしてビューの中央に配置し、青いガイドラインを使用した自動スナップを使用してこれを支援します。
ボタンを配置したら、一度に1つずつ選択して、制約を適用します。ボタンをクリックしてから、Interface Builderの右下にあるフローティングボタンからAlign Constraintsメニューを選択します(4つのセットが表示されます。整列は、左側の[フォームファクタ]ボタンの横にあるものです)。
このメニューで、Vertical Center In Containerチェックボックスをオンにし、値(おそらく0)の横にあるドロップダウンメニューをクリックして開きます。そのリストから、現在のキャンバス値を使用を選択します。次に、制約の追加ボタンを押します(おそらく1つの制約の追加とラベル付けされています) 。
これを行うと、Vertical Center In Containerの横の値がYオフセット値に設定されているのを見ると、おそらくそれが機能していることがわかります。 UIViewの配置を振り返ると、推測は正しいです。
Interface Builderを使用したくない場合はお詫びしますが、私はこれを自分で達成するのに苦労し、これらの手順について言及したいと思いました。いつでもIBを1回限りとして使用し、プログラムで制約をテストからログアウトしてから、それらを取得してコードのみのソリューションに適用することができます。
コードはありません。ストーリーボードで編集するだけです。
_label1
_、_label2
_、_label3
_、およびcell
があると仮定します
_// Center the labels
[NSLayoutConstraint constraintWithItem:label1 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual
toItem:cell.contentView attribute:NSLayoutAttributeCenterX
multiplier:1.0 constant:0]
[NSLayoutConstraint constraintWithItem:label2 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual
toItem:cell.contentView attribute:NSLayoutAttributeCenterX
multiplier:1.0 constant:0]
[NSLayoutConstraint constraintWithItem:label3 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual
toItem:cell.contentView attribute:NSLayoutAttributeCenterX
multiplier:1.0 constant:0]
// Vertical alignment/spacing of 8 between each label
[NSLayoutConstraint constraintWithItem:label1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
toItem:cell.contentView attribute:NSLayoutAttributeTop
multiplier:1.0 constant:0]
[NSLayoutConstraint constraintWithItem:label2 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
toItem:label1 attribute:NSLayoutAttributeBottom
multiplier:1.0 constant:8]
[NSLayoutConstraint constraintWithItem:label3 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
toItem:label2 attribute:NSLayoutAttributeBottom
multiplier:1.0 constant:8]
_
for()
ループ内にすべてをネストできるので、制約を繰り返す必要はありません。