LoginSignup
10
9

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-09-04

この記事は何?

SwiftUI Tutorials を進めていくうちに、宣言的なコーディング が少しずつわかってきたので、忘備録として投稿します。

実行環境

macOS 10.15 Catalina beta7
Xcode11 beta7

修飾子の書き方

チュートリアルの序盤で、次の画面を構築する手順があります。

スクリーンショット 2019-09-04 21.28.39.png

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

  • MapView(地図)
  • CircleImage(画像)
  • VStack(垂直に並べたテキスト)

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

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 構造体は以下のようなになります。

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 構造体は以下のようなコードです。

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

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

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

body プロパティ

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

body
var body: some View {...}

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

Viewプロトコル

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

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 はビューを1つだけ返す計算プロパティ
  • 修飾子は列挙できる
10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9