web-dev-qa-db-ja.com

AutoLayout制約を使用してUIViewを非表示にする

時々、レイアウトから削除したいサブビューがあります。非表示にするだけでなく、いわばビューの「フロー」の一部と見なすべきではありません。例:

enter image description here

オレンジ色のビューをプログラムで非表示にする戦略を探しています。ボックスのレイアウトとその内容は、自動レイアウトを介して行われます。注意すべき2つのこと:

  • オレンジ色のボックスは、コンテンツに基づいて垂直方向の高さを定義し、さらにマージンの上下のオフセットを定義しています。したがって、ラベルのテキストをnilに設定すると、ビューは内部マージンまで「縮小」されるだけで、高さは0になりません。
  • 同様に、3つのボックス間の垂直間隔は、オレンジ色のボックスの高さが0であっても、赤と黄色の間のギャップが必要な2倍になることを意味します。

可能な解決策

私の最善の提案は、オレンジ色のボックスに制約を追加し、高さを0に設定することです。これを機能させるには、オレンジ色のボックス内のすべての垂直制約に不要な優先順位を使用する必要があります。同時に、コンテナはボックスを区切る制約の定数を更新する必要があります。オレンジ色のボックスクラスは、スーパービューの動作を念頭に置いて内部の制約を定義しているため、このアプローチはあまり好きではありません。オレンジ色のボックスビューが、高さ0の制約自体を追加する 'collapse'メソッドを代わりに公開する場合、おそらく私はそれで生きることができます。

より良いアプローチはありますか?

29
Ben Packard

これを行うには、優先度の低い黄色のビューと赤色のビューの間に特別な制約を追加し、コードの優先度を調整します。

enter image description here

短い破線の制約(orangeToRedConがアウトレットです)の優先度は999です(必要な優先度を非必須に変更することはできないため、1000ではありません)。長い破線の制約(yellowToRedCon)の優先度は500で、定数は20です。コードでは、オレンジ色のビューを非表示にし、それらの優先度レベルを入れ替えることができます。 yellowToRedConの定数値に設定されます。

-(void)changePriorities {
    self.yellowToRedCon.priority = 999;
    self.orangeToRedCon.priority = 500;
    [UIView animateWithDuration:.5 animations:^{
        self.orangeView.alpha = 0;
        [self.view layoutIfNeeded];
    }];
}

この方法では、オレンジ色のビューの高さを変更する必要はありません。

69
rdelmar

IOS 9では、これに UIStackView を使用できます。古いバージョンのポリフィルもあります: TZStackView および OAStackView

14
fabb

できることは、オレンジ色のビューの高さの制約をアウトレットとして使用することです(アクセスできるようにするため)。次に、崩壊を次のようにアニメーション化します。

[UIView animateWithDuration:0.3 animations:^{
    orangeHeightConstraint.constant = 0;
    [self.view layoutIfNeeded]
}];

オレンジ色のビューには、赤色のビューに対する上部の制約と、黄色のビューに対する下部の制約が必要です。また、IBまたは[orangeView clipsToBounds]プログラムで

1
Jad Feitrouni

サブビューのすべての「必要な」スペースをサブビュー自体の一部として含めることで、これを解決します。このように、1。赤いビューの高さ=目に見える赤い部分+下部スペース2.オレンジのビューの高さ=目に見えるオレンジ色の部分+下部スペース3.黄色のビューの高さ=目に見える黄色+下部スペース

自動レイアウトによってオレンジビューの高さを0に設定すると、下部のスペースも自動的に0に縮小されます。

0