この記事は何?
SwiftUI Tutorials を進めていくうちに、宣言的なコーディング が少しずつわかってきたので、忘備録として投稿します。
実行環境
macOS 10.15 Catalina beta7
Xcode11 beta7
修飾子の書き方
チュートリアルの序盤で、次の画面を構築する手順があります。
この画面を構成している主なビューは、以下の通りです。
- MapView(地図)
- CircleImage(画像)
- VStack(垂直に並べたテキスト)
実際のコードは、以下のように記述しています。
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
構造体は以下のようなになります。
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
キーワードは省略されています。
struct LandmarkDetail: View {
var body: some View {
return VStack {...}
}
}
body プロパティ
body
プロパティこそが、まさしくSwiftUIの本体だとわかります。
var body: some View {...}
View
プロトコルに準拠した some
型として宣言されています。
some
型は「とりあえず、なんでもいい」型という表現に見えます。
つまり、body
は、アクセスされるたびに「何かしら View
プロトコルに準拠した型」の値が割り当てられる変数なんですね。
Viewプロトコル
View
プロトコルの宣言を見ると、body
がありました。
他には見当たりません。
View
プロトコルに準拠するには、body
を実装すればいいんですね。
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つだけ返す計算プロパティ - 修飾子は列挙できる