constraint を動的に追加 / 削除する
AutoLayout でレイアウトに必要な constraint を追加する場合、 Storyboard 上で指定する方法と、コードで指定する方法があります。
Storyboard では静的な constraint であれば簡単に追加できますが、動的に追加、そして削除したい場合には、コードで指定しなければならないと思います。
以下では、対象の constraint はつくられているとして、その constraint を動的に追加 / 削除する方法を記述します ( iOS8 以上) 。
方法は、メソッドによる指定とプロパティによる指定の 2 通りがあります。
メソッドによる指定
これらのメソッドは、引数に [NSLayoutConstraint]
をとるため、複数の constraint を 1 行で指定することができます。
let constraints = [hogeConstraint, fugaConstraint] NSLayoutConstraint.activateConstraints(constraints) // constraint の追加 NSLayoutConstraint.deactivateConstraints(constraints) // constraint の削除
プロパティによる指定
単一の constraint を指定する場合にはこちらの方法で良いかと思います。
個人的にはこちらの方が読みやすくて好きです。
hogeConstraint.active = true // constraint の追加 hogeConstraint.active = false // constraint の削除
注意点
注意したいのは、 削除した constraint を再び追加する場合です。
具体的には、 Stroyboard 上で指定した constraint を IBOutlet で接続し、それを状況に応じて削除、そして再び追加するということをしたい場合です。
このとき、constraint の参照を weak として IBOutlet で接続してしまうと、削除したのちに再び追加しようとするとエラーになってしまいます。
@IBOutlet internal var hogeConstraint: NSLayoutConstraint! // weak 参照 hogeConstraint.active = false hogeConstraint.active = true // 実行時エラーになる
このエラーを解消するためには、 参照を strong にする必要があるようでした。
@IBOutlet internal var hogeConstraint: NSLayoutConstraint! // strong 参照 hogeConstraint.active = false hogeConstraint.active = true // エラーにならない
追記
strong にする必要があると書きましたが、強参照にすると循環参照の恐れがあるので、weak のままで true にする直前にフォースアンラップ等で nil チェックをする方が良さそうかなという気がしています。