web-dev-qa-db-ja.com

自動レイアウト制約の有効化+無効化

単純な(と思う)問題があります。ストーリーボードで複数の制約を設定したUIImageViewがあります。

場合によっては、制約を無効にしてそのframeを手動で設定する必要がありますが、後でこれらの制約を再度有効にして、制約によって決定された場所にビューを戻します。 。

私はこれを次のようなものでできると思った:

_@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var constraint: NSLayoutConstraint!

func example() { 

    //to set its location and size manually
    imageView.removeConstraint(constraint) 
    imageView.frame = CGRectMake(...)

    //to cause it to return to its original position
    imageView.addConstraint(constraint) 

}
_

ただし、これではエラー2015-08-26 01:14:55.417 Constraints[18472:923024] The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0x7fbb72815f90 V:[_UILayoutGuide:0x7fbb72814c20]-(100)-[UIImageView:0x7fbb72814540]>が発生します。このエラーが発生する理由を誰もが知っていますか?

self.view.addConstraint(...)を呼び出してviewの代わりに制約を追加すると、エラーは取り除かれますが、イメージビューは本来の位置に戻りません。

setTranslatesAutoresizingMaskIntoConstraints(true)を呼び出さない限り、imageViewのフレームを問題なく設定できるようにするために、制約を削除したり無効にしたりする必要さえありません。

私はすでに this の質問を見ましたが、答えは不必要に複雑で、おそらく時代遅れで、さらには当てはまらないようです。

this の質問もありましたが、これは制約を再度有効にすることはできません-無効にする方法のみをカバーします。

activeプロパティを設定しようとしています:

_self.top.active = false
self.right.active = false
self.bottom.active = false
self.left.active = false

imageView.frame = CGRectMake(100, 100, 100, 100)
_

これにより、実際にはimageViewが表示されなくなります。 (ただし、すべての制約のactiveプロパティをfalseに設定しないと、imageViewは適切な位置に移動します。

ただし、実際の問題は、すべての制約のactiveプロパティをtrueに設定してイメージビューを元の場所に戻そうとしても、何も起こらないことです。 imageView.frame = CGRectMake(100, 100, 100, 100)で指定されたケース。

また、私のテストとJoachimBøggildの答え here によれば、制約のactiveプロパティがfalseに設定されている場合、その制約はnilになり、再アクティブ化できないようです。

配列に制約を追加し、それらを有効/無効にする:

興味深いことに、これはactiveプロパティの設定とほぼ同じ問題を引き起こします。すべての制約を配列arrayに配置し、NSLayoutConstraint.deactivateConstraints(array)を呼び出すと、画像ビューが消えます。また、後でNSLayoutConstraint.activateConstraints(array)を使用して制約を再アクティブ化しても、イメージビューは本来の場所に戻らず、元の場所にとどまります。

31
Randoms

あぁ!

activeプロパティがfalseに設定されると、制約はnilになります(したがって、再アクティブ化できません)。それらを作成する強い参照(命名法を整理してくれたCalebに感謝)は、それらを保存して、必要に応じて有効化および無効化できるようにします。

64
Randoms

NSLayoutConstraintのドキュメントを見ると、 Constraints というセクションがあり、これが active property 、これにより次のことがわかります。

このプロパティを変更することにより、制約をアクティブまたは非アクティブにできます...制約をアクティブまたは非アクティブにするには、この制約によって管理されるアイテムの最も近い共通の祖先であるビューでaddConstraint:およびremoveConstraint:を呼び出します。 addConstraint:またはremoveConstraint:を直接呼び出す代わりに、このプロパティを使用します。

そのため、問題の制約への参照strongを取得したら(アウトレットにある場合など)、次のことができます。単にactiveプロパティをfalse(またはObj-CのNO)に設定して無効にするか、true(またはYES)に設定します有効にします。

31
Caleb

ConstraintをIBOutletとしてストーリーボードからViewControllerに接続し、Array add all制約を配列に作成します。

使用中でない場合は、これらの制約を無効にします。

使用中に制約を追加します。

NSLayoutConstraint *constraint1;
NSLayoutConstraint *constraint2;
NSLayoutConstraint *constraint3;
NSArray *arr = @[constraint1,constraint2,constraint3];
 [NSLayoutConstraint deactivateConstraints:arr];

//After deactivate constraint array add what ever frame you want to add

//Activate  lateroN
[NSLayoutConstraint activateConstraints:arr];
1
Kavita