SwiftUI基礎:Type { … } は「クロージャ引数」の省略表現


NavigationStack { ... } などの「中かっこ」は、content: () -> View というクロージャ引数に渡しているだけ。
Type 自体がクロージャではない


1) 一番よく見る等式(まずはコレ)

省略版

NavigationStack {
    Text("Hello")
}

明示版(等価)

NavigationStack(content: {
    Text("Hello")
})
  • { ... }content 引数に渡すクロージャ
  • NavigationStackView(構造体) の初期化

2) 同じ仲間たち(全部おなじ省略ルール)

VStack

VStack {
    Text("A")
    Text("B")
}
// = VStack(content: { Text("A"); Text("B") })

WindowGroup

WindowGroup {
    ContentView()
}
// = WindowGroup(content: { ContentView() })

つまり Type { ... } を見たら Type(content: { ... }) に展開できる と覚える。


3) クロージャを“外出し”して渡す(引数である証拠)

let myContent: () -> some View = {
    Text("From variable closure")
}

NavigationStack(content: myContent)
  • ただの引数として渡せる=省略表現の正体がわかる

4) なぜ複数の View を並べられるの? → @ViewBuilder

NavigationStack(概念図)

struct NavigationStack<Content: View>: View {
    init(@ViewBuilder content: () -> Content)
}
  • contentビューを返すクロージャ
  • @ViewBuilder複数の View を並べる“文法糖” を提供(実際にはタプル等にまとめられる)

5) モディファイアでも同じ(おまけ)

sheet

.sheet(isPresented: $show) {
    DetailView()
}
// = .sheet(isPresented: $show, content: { DetailView() })

alert

.alert("エラー", isPresented: $showErr) {
    Button("OK", role: .cancel) {}
}
// = .alert("エラー", isPresented: $showErr, actions: { Button("OK", role: .cancel) {} })

**「中かっこ=クロージャ引数」**のパターンは、View 初期化だけでなく多くのモディファイアにも登場。


6) 3行まとめ(暗記カード)

  • Type { ... }Type(content: { ... }) に展開できる
  • 中かっこはクロージャTypeはView(構造体)
  • 迷ったら 明示版に“展開”して読む と仕組みが見える

7) 練習用ミニ課題(答えは下に)

Q1. 次の省略コードを明示版に展開してみよう

HStack {
    Image(systemName: "star")
    Text("Favorites")
}

A1(答え)

HStack(content: {
    Image(systemName: "star")
    Text("Favorites")
})

8) ついでに覚えると捗る周辺知識

  • @State:View 内の短期状態(値が変わると再描画)
  • @Binding:親の @State を“ひも”で共有($state を渡す)
  • @Environment:親やアプリ全体からの共有値(例:\.modelContext

これらも “クロージャの中で使われることが多い” ので一緒に押さえておくと、コードの流れが読みやすくなる。


参考コピペ:全部入りの最小サンプル

import SwiftUI

struct DemoView: View {
    @State private var show = false
    @State private var count = 0

    var body: some View {
        NavigationStack {                  // = NavigationStack(content: { ... })
            VStack(spacing: 12) {          // = VStack(content: { ... })
                Text("Count: \(count)")
                HStack {
                    Button("-1") { count -= 1 }
                    Button("+1") { count += 1 }
                }
                Button("Show Sheet") { show = true }
            }
            .padding()
        }
        .sheet(isPresented: $show) {       // = .sheet(isPresented: $show, content: { ... })
            VStack {
                Text("Sheet Content")
                Button("Close") { show = false }
            }
            .padding()
        }
    }
}

コメント

タイトルとURLをコピーしました