• トップ
  • ブログ一覧
  • 【Swift4】AutoLayoutをコードで実装してみた!
  • 【Swift4】AutoLayoutをコードで実装してみた!

    エンジニア記事エンジニア記事
    2019.04.03

    IT技術

    AutoLayoutの実装方法について簡単にまとめてみた

    高階さん 高階さん

    (株)ライトコードの高階(たかがい)です!

    StoryBoardでのAutoLayoutの実装はできるけど、コードで書いたことない!

    そんなあなた(私)のために、コードでの AutoLayout の実装方法について簡単にまとめてみました。

    今回は、ライブラリを使わずに標準の方法のみまとめていきます!

    開発環境

    MacOS10.14
    Swift4.2
    Xcode10.1
    Cocoapods1.6.1
    SnapKit4.0

    AutoLayoutとは?

    iOS デバイスの多様な画面サイズに View を適応させるレイアウトの仕組みのことです。

    座標やサイズを直接設定せず、相対的な値を View に制約(Constraint)として設定し、表示します。

    コードで AutoLayout  実装する方法は、以下の2つの方法があります。

    1. NSLayoutConstraint
    2. NSLayoutAnchor

    実際に書いて動かした方が早いので早速やっていきます!

    が、その前にコードで AutoLayout を実装する際の注意点から。

    コードで実装するときに注意するポイント2点

    まず最初に注意して欲しいのが、必ず View を配置(addSubView)してから制約を設定すること

    注意点1

    配置前に制約を設定すると、実行時に以下のエラーでクラッシュします。

    The view hierarchy is not prepared for the constraint:

    注意点2

    もう一点は、translatesAutoresizingMaskIntoConstraints をオフにすること

    {制約を設定するView}.translatesAutoresizingMaskIntoConstraints = false

    Viewを配置する前に上の一行を書いちゃいましょう。

    ちなみに、この「translatesAutoresizingMaskIntoConstraints」というプロパティについてですが、AutoLayout 以前に使われていた「Autosizing」というレイアウトの仕組みを、AutoLayout に変換するかどうかを設定するフラグだそうです。

    高階さん 高階さん
    デフォルトではtrueになっていますが、追加していく AutoLayout の制約が Autosizing の制約とコンフリクトを起こすと期待通りの動作をしないことがあります。そのため、新たに制約を追加する際には忘れずに false にしてください

    実装について

    では、早速それぞれの実装方法を見ていきましょう。

    今回は、比較のために以下のように、中央に100pt四方の赤い View を表示させていきたいと思います。

    1.NSLayoutConstraint

    こちらは、NSLayoutConstraint クラスのイニシャライザを利用した方法です。

    イニシャライザの定義は、以下のようになっています。

    1public convenience init(
    2        item view1: Any, 
    3        attribute attr1: NSLayoutConstraint.Attribute, 
    4        relatedBy relation: NSLayoutConstraint.Relation, 
    5        toItem view2: Any?, 
    6        attribute attr2: NSLayoutConstraint.Attribute, 
    7        multiplier: CGFloat, 
    8        constant c: CGFloat
    9)
    高階さん 高階さん
    引数がてんこ盛りなのでぱっと見で分かりづらいですね。。

    引数について

    たくさんある引数について順に説明していきます。

    引数名渡すもの
    item追加するView
    attribute(attr1)追加するViewの設定をする部分
    relatedBy追加するViewと基準となるViewの関係性
    toItem基準となるView
    attribute(attr2)基準となるViewの基準となる部分
    multipier制約の割合の数値
    contant制約で追加する数値

    仮に、relatedBy を .equal とした時の状態を簡潔に表すと

    item.attribute(attr1) = toItem.attribute(attr2) * multiplier + constant

    となります。

    実際にコードを書いてみる!

    以下は、100pt 四方の View を画面中央に表示させるコードです。

    引数を色々といじってみた方が理解が早いと思うので、そちらをお試しください。

    1let view1 = UIView()       // 追加するViewを生成
    2view1.backgroundColor = UIColor().red    // 確認用に色を変更
    3view1.translatesAutoresizingMaskIntoConstraints = false
    4view.addSubview(view1)         // 親Viewに配置
    5
    6view.addConstraints([          // 生成した制約を設定する
    7        NSLayoutConstraint(    // 制約を生成
    8                item: view1,
    9                attribute: .width,
    10                relatedBy: .equal,
    11                toItem: view,
    12                attribute: .width,
    13                multiplier: 0.0,
    14                constant: 100
    15        ),
    16        NSLayoutConstraint(
    17                item: view1,
    18                attribute: .height,
    19                relatedBy: .equal,
    20                toItem: view,
    21                attribute: .height,
    22                multiplier: 0.0,
    23                constant: 100
    24        ),
    25        NSLayoutConstraint(
    26                item: view1,
    27                attribute: .centerX,
    28                relatedBy: .equal,
    29                toItem: view,
    30                attribute: .centerX,
    31                multiplier: 1.0,
    32                constant: 0.0
    33        ),
    34        NSLayoutConstraint(
    35                item: view1,
    36                attribute: .centerY,
    37                relatedBy: .equal,
    38                toItem: view,
    39                attribute: .centerY,
    40                multiplier: 1.0,
    41                constant: 0.0
    42        )
    43])

    2. NSLayoutAnchor

    次は、iOS9 で追加された NSLayoutAnchor クラスを利用して表示させる方法です。

    こちらは、NSConstraint よりも、かなり簡潔に書くことができます。

    実際にコードを書いてみる!

    NSLayoutConstraint クラスを利用して表示させたものと同じものを表示させるコードが以下になります。

    1let view1 = UIView()
    2view1.backgroundColor() = .red
    3view1.translatesAutoresizingMaskIntoConstraints = false
    4view.addSubview(view1)
    5
    6view1.widthAnchor.constraint(equalToConstant: 100).isActive = true    // 幅を100ptに設定する制約を有効にする
    7view1.heightAnchor.constraint(equalToConstant: 100).isActive = true   // 高さを100ptに設定する制約を有効にする
    8view1.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true    // X座標軸の中心を親Viewと合わせる制約を有効にする
    9view1.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true    // Y座標軸の中人を親Viewと合わせる制約を有効にする
    高階さん 高階さん
    結構短くなりましたね!

    Anchor は、View の端や寸法を表すので、Attribute とほぼ同じです。

    引数について

    Anchor の指定後に constraint メソッドで制約を付与していますが、こちらのメソッドは制約の内容により引数が異なります

    1. 値を定数のみで指定したい場合は、equalToConstant: を、Anchorを指定したい場合は、equalTo: を指定する
    2. 指定したAnchorの値を2倍にしたり1/2にしたい場合は、equalTo: の後にmultiplier: の引数を追加
    3. 指定したAnchorの値の2倍+10ptなどの指定をしたい場合はmiltiplier: の後にさらにconstant: の引数を追加

    最後に制約を生成した後に isActive プロパティを true にしていますが、こちらは生成した制約をレイアウト構築時に反映させるかどうかを制御するフラグになります。

    高階さん 高階さん
    デフォルトでは、「false」となっており、「true」としない限りは制約が反映されないため、必ず制約の生成時に true に変更してください!

    次回の記事に続く

    NSLayoutConstraint はさておき、NSLayoutAnchor に関しては、思っていたよりもシンプルで分かり易かったです。

    これなら、コードでの AutoLayout も割と楽に書けそうですね。

    ただ、AutoLayout をさらに簡単にするライブラリがあるようなので、次の内容ではライブラリについてまとめていきたいと思います!

    次の記事

    featureImg2019.04.18【Swift4】SnapKitがめちゃくちゃ便利だった件SnapKitというライブラリを使ってみる 高階さん(株)ライトコードの高階(たかがい)です!前回の記事では、NSLa...

    こちらの記事もオススメ!

    featureImg2020.08.14スマホ技術 特集Android開発Android開発をJavaからKotlinへ変えていくためのお勉強DelegatedPropert...

    featureImg2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...

    エンジニア記事

    エンジニア記事

    おすすめ記事

    GitHubActionsのランナーに触れてみた

    こやまん(エンジニア)

    こやまん(エンジニア)

    2024.03.28

    IT技術

    Azure Data FactoryでSlackへ通知をしてみる

    たかやん(エンジニア)

    たかやん(エンジニア)

    2024.03.28

    IT技術

    GCP Secret Managerを使ってみた

    たなゆー(エンジニア)

    たなゆー(エンジニア)

    2024.03.21

    IT技術

    Bitriseのパイプラインと環境変数

    加納(エンジニア)

    加納(エンジニア)

    2024.03.11

    IT技術