SwiftUIの宣言的コーディングの読み方

# この記事は何？
[SwiftUI Tutorials](https://developer.apple.com/tutorials/swiftui) を進めていくうちに、__宣言的なコーディング__ が少しずつわかってきたので、忘備録として投稿します。

## 実行環境
macOS 10.15 Catalina beta7
Xcode11 beta7

# 修飾子の書き方
チュートリアルの序盤で、次の画面を構築する手順があります。

![スクリーンショット 2019-09-04 21.28.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70476/9d761cbf-117e-34d6-baa9-cb2d7f71049d.png)

この画面を構成している主なビューは、以下の通りです。

- MapView（地図）
- CircleImage（画像）
- VStack（垂直に並べたテキスト）

実際のコードは、以下のように記述しています。

````Swift:SwiftUIの宣言的コーディング
struct LandmarkDetail: View {
    var body: some View {
        VStack {
            MapView()
                .edgesIgnoringSafeArea(.top)
                .frame(height: 300)
            CircleImage()
                .offset(y: -130)
                .padding(.bottom, -130)
            VStack(alignment: .leading) {
                Text("Turtle Rock")
                    .font(.title)
                HStack {
                    Text("Joshua Tree National Park")
                        .font(.subheadline)
                    Spacer()
                    Text("California")
                        .font(.subheadline)
                }
            }
            .padding(.all)
            Spacer()
        }
    }
}
````
`.xxx()` は、修飾子と呼ばれまが、実際にはプロパティ値の指定と理解できます。
長ったらしく捉えると、この `LandmarkDetail` 構造体は以下のようなになります。

````Swift:SwiftUIの宣言的コーディング
struct LandmarkDetail: View {
    var body: some View {
        VStack {
            MapView().edgesIgnoringSafeArea(.top)
            MapView().frame(height: 300)
            CircleImage().offset(y: -130)
            CircleImage().padding(.bottom, -130)
            VStack(alignment: .leading) {
                Text("Turtle Rock").font(.title)
                HStack {
                    Text("Joshua Tree National Park").font(.subheadline)
                    Spacer()
                    Text("California").font(.subheadline)
                }
            }
            .padding(.all)
            Spacer()
        }
    }
}
````
抽象的に捉えると、この `LandmarkDetail` 構造体は以下のようなコードです。

````Swift:
struct LandmarkDetail: View {
    var body: some View {
        VStack {
            MapView()
            CircleImage()
            VStack() {
                Text("Turtle Rock")
                HStack {
                    ...
                }
            }
        }
    }
}
````

`body` メンバープロパティがあるだけです。
この変数 `body` は、計算プロパティになっていますが、ひとつの `VStack` だけを返しているので、`return` キーワードは省略されています。

````Swift:returnキーワードを明示
struct LandmarkDetail: View {
    var body: some View {
        return VStack {...}
    }
}
````

## body プロパティ
`body` プロパティこそが、まさしく__SwiftUIの本体__だとわかります。

````Swift:body    
var body: some View {...}
````

`View` プロトコルに準拠した `some`型として宣言されています。
`some` 型は「とりあえず、なんでもいい」型という表現に見えます。
つまり、`body` は、アクセスされるたびに「何かしら `View` プロトコルに準拠した型」の値が割り当てられる変数なんですね。

## Viewプロトコル
`View` プロトコルの宣言を見ると、`body` がありました。
他には見当たりません。
`View` プロトコルに準拠するには、`body` を実装すればいいんですね。

````Swift:Viewプロトコルの宣言
public protocol View {
    /// The type of view representing the body of this view.
    ///
    /// When you create a custom view, Swift infers this type from your
    /// implementation of the required `body` property.
    associatedtype Body : View

    /// Declares the content and behavior of this view.
    var body: Self.Body { get }
}

````

コメントには
_このビューの本体を表現するビューの型
カスタムビューを作成すると、必須プロパティ `body` の実装から型が推論される_
...とあります。

## 考察
今のところ、SwiftUI宣言的コーディングの理解は...

- `View` プロトコルに準拠させる
- `body` はビューを１つだけ返す計算プロパティ
- 修飾子は列挙できる