画面レイアウトもstoryboardを使わずに実装する上では、避けて通れそうにないのが、Autolayoutの実装方法をまとめます。
コードで実装するメリットは、複数の部品をまとめて設定することができることです。
後述するように、Autolayoutのコーディングは結構行数が増えることになるので、画面(VIEW)の実装とは、クラスを分けて管理するということにもします。
■Autolayoutの実装の基本
基本的には、このページを参考にしました→「コードでAutolayout – Qiita」
Autolayoutの実装は、親ViewにaddConstraintsでNSLayoutConstraintクラス(制約)を加えていくことで実装します。NSLayoutConstraintのコンストラクターで、制約を定義します。(ちなみに、addConstraintではなく、addConstraintsを利用する。これ、最初すごいハマった)
引数 | 説明 |
item | 制約を追加するview。 |
attribute | 制約対象の属性。高さとか幅とか、置く場所のX座標やY座標など |
relateBy | 計算式の関係性(概ねEqualで事足りる) |
toItem | 制約の基準(位置計算に使用する)のview |
attribute | toItemの属性。 |
multiplier | 乗算値(上記のattributeを何倍にするか。これもだいたい1) |
constant | 定数値(隙間を固定的に開けたい時とかに使う) |
と書いてもちょっとわかりにくい。例えば、以下のようなコードになる。
画面!.addConstraints([ NSLayoutConstraint(item: 項目ラベル,attribute: NSLayoutAttribute.Left,relatedBy: NSLayoutRelation.Equal, toItem: 画面,attribute: NSLayoutAttribute.Left,multiplier: 1.0,constant: 10 )
この場合は、「項目ラベルの左(LEFT)座標=画面の左(LEFT)座標×1.0+10」という意味。
式の左辺と右辺という風に捉えれば、考えやすい。
■複数のラベルを一気に設定する。
上記の基本さえわかれば、複数のラベルをfor文を利用して、一気に設定することができます。
以下のコードは、配列で管理している一連のラベルを一気に設定します。最初のラベルだけ、画面の上端を基準に設定し、それ以外は先に設定したラベルの下端を基準に上端を設定しています。
var 前ラベル=画面!.項目名ラベル集[0] var 最初か否か:Bool=true for 項目ラベル in 画面!.項目名ラベル集{ if 最初か否か{ 画面!.addConstraints([ NSLayoutConstraint(item: 項目ラベル,attribute: NSLayoutAttribute.Top,relatedBy: NSLayoutRelation.Equal, toItem: 画面,attribute: NSLayoutAttribute.Top,multiplier: 1.0,constant: 5 )]) 最初か否か=false } else{ 画面!.addConstraints([ NSLayoutConstraint(item: 項目ラベル,attribute: NSLayoutAttribute.Top,relatedBy: NSLayoutRelation.Equal, toItem: 前ラベル,attribute: NSLayoutAttribute.Bottom,multiplier: 1.0,constant:5 ) ]) } 前ラベル=項目ラベル 画面!.addConstraints([ NSLayoutConstraint(item: 項目ラベル,attribute: NSLayoutAttribute.Left,relatedBy: NSLayoutRelation.Equal, toItem: 画面,attribute: NSLayoutAttribute.Left,multiplier: 1.0,constant: 10 ), NSLayoutConstraint(item: 項目ラベル,attribute: NSLayoutAttribute.Width,relatedBy: NSLayoutRelation.Equal, toItem: nil,attribute: NSLayoutAttribute.Width,multiplier: 1.0,constant: 画面!.項目名幅+20 ) ]) }
■AutoLayoutの設定を別クラスにする。
上記のように、設定していると結構コード量が増えてしまいます。そのため、上記のような部分は別クラスにしました。
以下のような制約クラスを作成しました。
import UIKit class 公演画面制約型{ var 画面: 公演画面型? = nil func 項目名ラベル配置(){ //略 NSLayoutConstraintを画面にaddConstraintsする関数を記述 } }
画面のクラスの方では、上記のクラスのインスタンスを定義して、selfを制約クラスの画面プロパティにセットして、関数をコールするだけです。