web-dev-qa-db-ja.com

Swiftでプログラムによってレイアウト制約を変更する方法は?

各セルにtextViewがあるコレクションビューがあります。これはセットアップされた私のtextview制約です

textView.topAnchor.constraint(equalTo: object1.bottomAnchor).isActive = true
textView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true

...そして私のtextViewの幅と高さ。

次に、if条件により、textViewのtopAnchorをオブジェクト1の下部アンカーではなく、オブジェクト2の下部アンカーに変更します。ただし、以下のコードを入力すると、Willは制約エラーを解除して回復しようとします。

すでに設定されている上部アンカーを変更する方法を誰かが知っていますか?

if (aCondition){
textView.topAnchor.constraint(equalTo: object2.bottomAnchor).isActive = true
}else{
  textView.topAnchor.constraint(equalTo: object1.botttomAnchor).isActive = true
}
7
KevinVuD

古いアクティブな制約を非アクティブにする必要があります。現在、新しい制約をビューに追加しているだけです。したがって、最初に、制約への参照を維持する2つのプロパティを作成することをお勧めします。

_fileprivate var topConstraint1: NSLayoutConstraint?
fileprivate var topConstraint2: NSLayoutConstraint?
_

次に、最初に、UIを作成するときに、適切に初期化します。

_topConstraint1 = textView.topAnchor.constraint(equalTo: object1.bottomAnchor)
topConstraint2 = textView.topAnchor.constraint(equalTo: object2.bottomAnchor)
_

そして最初にアクティブにしたいものをアクティブにします:

_topConstraint1?.isActive = true
_

次に、制約を変更する場合は、まず非アクティブにする必要があるものを非アクティブにしてから、正しいものをアクティブにします。

_if aCondition {
    topConstraint1?.isActive = false
    topConstraint2?.isActive = true
} else {
    topConstraint2?.isActive = false
    topConstraint1?.isActive = true
}
_

PS:最初に古いものを非アクティブにしてから新しいものをアクティブにする必要があります。そうしないと、新しいものをアクティブにしたときに古いものと競合し、コンソールに警告が表示されます。

P.S.2:複数の制約を一度にアクティブ化する場合は、NSLayoutConstraint.activate(_:)を使用します- documentation のように、より効率的です。

通常、この方法を使用すると、各制約を個別にアクティブにするよりも効率的です。

だから例えば、代わりに:

_someConstraint1.isActive = true
someConstraint2.isActive = true
_

むしろ使用:

_NSLayoutConstraint.activate([someConstraint1, someConstraint2])
_

同じことが制約の非アクティブ化と NSLayoutConstraint.deactivate(_:) にも当てはまります。

22
Milan Nosáľ