NRIネットコム Blog

NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

【UIKit】Storyboardを使わずにコードでAuto Layoutを設定し、SwiftUIのプレビューでViewを確認する方法

概要

Auto Layoutとはビューに設定された制約に基づいて、ビュー階層内のすべてのビューのサイズと位置を動的に計算するレイアウトでその制約などは主にStoryboardを使用して定義します。
今回の記事ではStoryboardを使わずにコードでAuto Layoutを設定する方法を紹介します。

今回の記事で作成できる成果物の様子

Auto Layoutについてもっと知りたいという方は以下参照ください。

Auto Layout Guide: Understanding Auto Layout

環境

この記事は以下のバージョン環境のもと作成されたものです。
【Xcode】14.1
【iOS】16.1
【macOS】Monterey バージョン 12.6

translatesAutoresizingMaskIntoConstraintsをfalseにする

まず適当なViewControllerを作成します。
そのViewControllerの中でラベルを作成します。

lazy var myLabel: UILabel = {
    let label:UILabel = UILabel()
    label.frame = CGRect(x: 0, y: 0, width: 200, height: 50)
    label.text = "Open MyViewController"
    label.textColor = .black
    return label
}()

続いてAuto Layoutを設定するファンクションを追加します。

private func addMyLabel() {
    myLabel.translatesAutoresizingMaskIntoConstraints = false
    self.view.addSubview(myLabel)
    myLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    myLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
}

ここで必要なのがtranslatesAutoresizingMaskIntoConstraintsをfalseにすることです。
コードベースでAuto Layoutを設定する場合はtranslatesAutoresizingMaskIntoConstraintsをfalseにする必要があります。
translatesAutoresizingMaskIntoConstraintsについてざっくり説明するとfalseにすることでコードベースで定義したAuto Layoutを反映させることができます。
更に詳細を知りたい方は以下ドキュメントを参照ください。
Apple Developer Documentation
UILabelで定義したテキストを画面の中央に表示するサンプルコードは以下の通りです。

class MyViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        addMyLabel()
    }

    lazy var myLabel: UILabel = {
        let label:UILabel = UILabel()
        label.frame = CGRect(x: 0, y: 0, width: 200, height: 50)
        label.text = "Open MyViewController"
        label.textColor = .black
        return label
    }()

    private func addMyLabel() {
        myLabel.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(myLabel)
        myLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        myLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    }
}

myLabelはUILabelに準拠させ、クロージャー内でUILabelの大きさや、テキスト、テキストの色などを定義しています。
そのUILabelをaddMyLabelメソッドの中にあるaddSubviewの引数に渡します。
後はviewに対してcenterYAnchorやcenterXAnchorを定義することで画面の中央にUILabelが表示させることができます。
これで以下のようなViewができます。

SwiftUIのプレビューを使用する

まずUIViewControllerRepresentableを使用してMyViewControllerをSwiftUIで使用できるように変換します。
UIViewControllerRepresentableに関しては別の記事で解説しますのでそちらをみていただければと思います。

struct MyViewControllerRepresentable : UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> MyViewController {
        return MyViewController()
    }
    func updateUIViewController(_ uiViewController: MyViewController, context: Context) {

    }
}

これでSwiftUIのプレビューを使用できるようになります。
以下のようにプレビューを作り、そのなかでMyViewControllerRepresentableを呼びます。

struct MyViewController_Previews: PreviewProvider {
    static var previews: some View {
        MyViewControllerRepresentable()
    }
}

動作状況はこんな感じです。
(2倍速で見ていただくとちょうど良いかもしれません)

youtu.be

まとめ

Storyboardを使わずにコードでAuto Layoutを設定し、SwiftUIのプレビューでViewを確認する方法でした。
コード量は増えるものの、レイアウトをコードで確認できるは個人的に好きです!
またプレビューと組み合わせることで瞬時にViewの変更を確認しつつレイアウトを組めるので是非お試しください。

執筆者岡優志

iOSエンジニア
iOSを専門とし、モバイルアプリの開発を行なっています。

Twitter