[SwiftUI]SwiftUIがContentViewや、View Objectを配置する仕組み。Modifierの有無や、その順番による結果の違いなど

SwiftUIにおいては既存のUIKitとは異なり、コードベースでView Objectを配置していきますが、慣れるまではなかなか思ったとおりに配置できなかったりします。そこで、簡単な例を基にSwiftUIにおいて、ContentViewや各View Objectがどのようにサイズを決定し、配置されていくのかをスライドを使って整理したいと思います。

.background Modifierを1つ使った例

小さくて見づらいですが、右図のように、デフォルトフォントで”Hello”と表示し、背景をbackgroundモディファイヤで赤くする際の内部動作の仕組みを概念的にみていきたいと思います。

struct ContentView: View {
    var body: some View {
            Text("Hello")
                .background(Color.red)
    }
}

このとき重要なコンセプトとしてModified Contentというものがあります。

Modified Content

以下のように記載すれば、いわゆる通常のView ObjectであるTextとなります。

Text(“Hello”)

このTextをカスタマイズするため、各Modifierを付与すると、Modified Contentと呼ばれるObjectになります。各Modified Contentは階層的にOriginalのView(ここではText)とModifier(ここでは.background)を保持しています。

Text(“Hello”)
.background(Color.red)

.backgroundと.paddingの2つのModifierを使った例

次にbackgroundに加えpaddingのModifierを使った例でみていきます。

struct ContentView: View {
    var body: some View {
            Text("Hello")
                .padding(60)
                .background(Color.red)
    }
}

このとき重要になってくるのはModifierの記載順序です。スライドの通り、下に書いたものから順に尋ねていきますので、下に書いたものから処理されるイメージになります。以下の2つの例で実際の表示の違いが確認できます。

struct ContentView: View {
    var body: some View {
            Text("Hello")
                .padding(20)
                .background(Color.red)
                .padding(60)
    }
}
  1. TextでHelloを表示
  2. 表示したHelloの領域を20pt分Padding
  3. 20pt分Paddingした背景を赤色に
  4. 背景を赤色にしたものの領域を60pt分Padding
struct ContentView: View {
    var body: some View {
            Text("Hello")
                .background(Color.red)
                .padding(60)
    }
}
  1. TextでHelloを表示
  2. 表示したHelloの背景を赤色に着色
  3. 背景を赤色にしたものの領域を60pt分Padding

まとめ

SwiftUIでのレイアウトの仕組みは実はシンプルなのですが、公式ドキュメントも文字情報の比重が大きいためとっつきにくいかもしれません。このように図示することで理解が容易になると思います。

参考サイト

https://www.hackingwithswift.com/books/ios-swiftui/how-layout-works-in-swiftui