はじめに
どうも、はじめです。
今回はコードでoutlayoutを変更する方法を覚えたので
記事にしてみようと思います。
今回紹介する方法は以下の3つです。
1.NSLayoutConstraintのActiveを切り替える
2.NSLayoutConstraintのActiveを切り替える(複数同時)
3.NSLayoutConstraintの値を変更する
今回は例として
ボタンを押すと画面中央に配置してあるViewのサイズが変更するものを
作ってみようと思います。
ではさっそくー
前提条件
Xcode 8.3.3
Swift 3.1
事前準備
まずは画面中央に表示するViewを配置します。
(サイズが変わっていることが分かるように背景を変えています。)
追加したViewに対して以下の制約を追加します。
※Aspectは1:1に設定しておきます。
左側の余白を定めた制約をoutlet接続します。
(以後DefaultMarginと呼びます)
次にボタンを押された後に反映したい制約も追加し、
outlet接続します。
・LeftMargin = 10
・LeftMargin = 100
この時制約の重複が発生するためstoryboard上でうまく変わってくれません。
先ほど追加したDefaultMarginの制約を選択し、installendのチェックを外します。
これで制約のActiveをfalseにすることができます。
最後にボタンを配置し、actionメソッドを作成します。
事前準備は以上になります。
1.NSLayoutConstraintのActiveを切り替える
OutLet接続した制約に対し、
isActiveの値を変更することで有効無効を切り替えることができます。
制約の変更をアニメーションさせたい場合はanimateメソッドないで
self.view.layoutIfNeeded()
と記載すると変更した制約をアニメーションさせることができます。
上記の方法で50のボタンが押された時の処理を実装します。
1 2 3 4 5 6 7 8 9 10 11 | @IBAction func enableDefaultMargin(_ sender: Any) { // それぞれの制約のisActiveの値を変更する shotMargin.isActive = false longMargin.isActive = false defaultMargin.isActive = true // 制約の変更をアニメーションさせる UIView.animate(withDuration: 0.5, animations: { self.view.layoutIfNeeded() }) } |
2.NSLayoutConstraintのActiveを切り替える(複数同時)
方法としては1と同じですがこちらの方法は複数の制約を切り替えたい場合に
見やすくかけるようになると思います。
上記の方法で10のボタンが押された時の処理を実装します。
1 2 3 4 5 6 7 8 9 10 11 | @IBAction func enableShotMargin(_ sender: Any) { // NSLayoutConstraint型の変数を配列で渡して、 // 複数の制約のisActiveの値を変更する let deActiveConstraints: [NSLayoutConstraint] = [defaultMargin, longMargin] NSLayoutConstraint.deactivate(deActiveConstraints) NSLayoutConstraint.activate([shotMargin]) UIView.animate(withDuration: 0.5, animations: { self.view.layoutIfNeeded() }) } |
以上で今回の実装は終わりです。
最終的な全ソースを載せておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | import UIKit class ViewController: UIViewController { @IBOutlet weak var defaultMargin: NSLayoutConstraint! @IBOutlet weak var shotMargin: NSLayoutConstraint! @IBOutlet weak var longMargin: NSLayoutConstraint! override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } @IBAction func enableDefaultMargin(_ sender: Any) { // それぞれの制約のisActiveの値を変更する shotMargin.isActive = false longMargin.isActive = false defaultMargin.isActive = true // 制約の変更をアニメーションさせる UIView.animate(withDuration: 0.5, animations: { self.view.layoutIfNeeded() }) } @IBAction func enableShotMargin(_ sender: Any) { // NSLayoutConstraint型の変数を配列で渡して、 // 複数の制約のisActiveの値を変更する let deActiveConstraints: [NSLayoutConstraint] = [defaultMargin, longMargin] NSLayoutConstraint.deactivate(deActiveConstraints) NSLayoutConstraint.activate([shotMargin]) UIView.animate(withDuration: 0.5, animations: { self.view.layoutIfNeeded() }) } @IBAction func enableLongMargin(_ sender: Any) { shotMargin.isActive = false defaultMargin.isActive = false longMargin.isActive = true longMargin.constant = 150 UIView.animate(withDuration: 0.5, animations: { self.view.layoutIfNeeded() }) } } |
3.NSLayoutConstraintの値を変更する
最後に今回の実装では使用していませんがoutlet接続した制約の値を変更する方法があります。
例としてボタンを押された時、100ある余白を150に変更する処理を書くと以下のようになります。
1 2 3 4 | longMargin.constant = 150 UIView.animate(withDuration: 0.5, animations: { self.view.layoutIfNeeded() }) |
さいごに
最近スクロールビューを使用する機会があったのですが、
なんじゃこのオートレイアウトは。。。ってなりましたw
CollectionViewも先日初めて使いましたがまだまだ使い慣れないので、
早く使い慣れたいです。
今回も最後まで見ていただいてありがとうございました。