コンテナViewの再描画を誘発させるには状態変数@Stateの値を変える。コンテナViewとはNavigationStack, TabView, NavigationSplitView, LazyVGrid…などである。コンテナView単独ではViewを構成出来ず、単純View、基本Viewとでも言えるコンテナViewではないViewをコンテナViewへ格納することでViewを構成する。
状態変数@Stateの値を変えるにはコンテナViewではないView、例えばButton, Toggle, TextField, Picker, Stepper, Slider…がある。(Swiftポケットリファレンス第三版 Chapter6 2024)
コンテナViewではないViewにはコンテンツを表示するText, Image, Shape, List, Table…がある。Viewの全リストはXcodeを起動しDeveloper Documentationを開きView Protocolを検索すれば取得できる。検索結果の下の方のConforming Typesにアルファベット順に記載されている。この中にはDisclosureGroupの様な珍しいViewも現れる。
ここではNavigationStackの再描画、つまり画面遷移を状態変数pathを使って行う例を示す。コンテナViewの中にはToggleとButtonが入っている。空のpathコレクションに値が投入されると画面再描画が発生し画面遷移が起こる。戻るButtonが押下されるとpathコレクションの中身はpopされ空の状態に戻る。
遷移先はnavigationDestinationモディファイアで指定する。closureにはpathに投入された値がセットされる。navigationDestinationモディファイアには、セットされる値の型までは知らされない。型情報も同時に引数に与えて教える必要がある。

遷移先として指定されているVStackに付与されているframeモディファイアはTextに付与しても良い。
struct ContentView: View {
@State var path: NavigationPath = NavigationPath()
@State var vibrateOnRing : Bool = false
var body: some View{
NavigationStack(path: $path){
Toggle(
"Vibrate on Ring",
systemImage: "dot.radiowaves.left.and.right",
isOn: $vibrateOnRing
).toggleStyle(.switch)
.onChange(of: vibrateOnRing) { _, newValue in
path.append(1)
}
Button("遷移する"){
path.append(0)
// withAnimation { path.append(0) }
}
.navigationTitle("ホーム")
.navigationDestination(for: Int.self) { e in
VStack {
// Color.clear // 背景を広げるために入れても良い
Text("hoge\(e)")
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
}
}
}
}
