Closed konohazukux closed 4 months ago
f0875010cdf52627e537ca958ece557482da6707
クロージャーで戻す 1d8c7ed26554769a3b6116bc7afcd5245f548d6d
SwiftUIの@Bindingや@Environment、@Stateなどのプロパティラッパーは、ビュー間での状態管理やデータ共有を簡単に行うために設計されていますが、特定の要件や状況に応じて、クロージャーやデリゲートパターンを使用することも引き続き可能です。
とのことなので、基本的には @Bindingや@Environment、@State などを使用した方が良さそう
SwiftUIでは、従来のUIKitで使用されていたデリゲートやクロージャーに加えて、データの受け渡しや状態管理に特化した新しい方法を提供しています。ただし、デリゲートやクロージャーを使用して値を渡すことも可能です。以下に、クロージャーを使用して遷移元に値を渡す方法を説明します。
ProductDetailView
にクロージャーを追加し、ProductCategoryView
からクロージャーを渡す方法です。
ProductDetailView
にクロージャーを追加ProductDetailView
にクロージャープロパティを追加します。
import SwiftUI
struct ProductDetailView: View {
let title: String
@State private var value1: String = "--"
var onValueChange: (String) -> Void
var body: some View {
VStack {
Text("Hello, \(title)")
.padding(.bottom, 20)
Text("\(value1)")
.padding(.bottom, 20)
HStack {
Button(action: {
self.value1 = "OK"
self.onValueChange(self.value1) // クロージャーを呼び出す
}, label: {
Text("OK")
})
.padding(.horizontal, 20)
Button(action: {
self.value1 = "NG"
self.onValueChange(self.value1) // クロージャーを呼び出す
}, label: {
Text("NG")
})
.padding(.horizontal, 20)
}
Spacer()
}
}
}
#Preview {
ProductDetailView(title: "タイトル", onValueChange: { _ in })
}
ProductCategoryView
からクロージャーを渡すProductCategoryView
で、ProductDetailView
にクロージャーを渡します。
import SwiftUI
struct ProductCategoryView: View {
@Binding var productCategory: ProductCategory
@State private var selectedValue: String = "--" // Stateプロパティを追加
var body: some View {
NavigationView {
VStack {
HStack {
Text(productCategory.title)
Spacer()
Image(systemName: productCategory.isCompleted ? "checkmark.circle.fill" : "circle")
.foregroundColor(productCategory.isCompleted ? .green : .gray)
.onTapGesture { }
}
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach(productCategory.items) { item in
NavigationLink(destination: ProductDetailView(title: item.title, onValueChange: { newValue in
self.selectedValue = newValue // クロージャーで値を受け取る
})) {
ProductItemView(item: item)
}
}
}
}
Text("Selected Value: \(selectedValue)") // 選択された値を表示
}
.padding(.horizontal, 10)
}
}
}
#Preview {
ProductCategoryView(productCategory: .constant(ProductCategory(title: "Sample Category", isCompleted: false, items: [ProductItem(title: "Sample Item")])))
}
この方法では、ProductDetailView
で値が変更されたときに、クロージャーを通じてその値がProductCategoryView
に渡され、selectedValue
として表示されます。クロージャーを使用することで、UIKitでのデリゲートパターンに似た方法でデータの受け渡しが可能になります。
SwiftUIの@Binding
や@Environment
、@State
などのプロパティラッパーは、ビュー間での状態管理やデータ共有を簡単に行うために設計されていますが、特定の要件や状況に応じて、クロージャーやデリゲートパターンを使用することも引き続き可能です。
ProductDetailView
からProductCategoryView
に値を戻すには、Binding
を使用して状態を共有する方法が適しています。以下に、その実装方法を示します。まず、
ProductDetailView
に戻したい値を受け取るためのBinding
プロパティを追加します。次に、
ProductCategoryView
でvalue1
の状態を保持するために、@State
プロパティを追加し、それをProductDetailView
に渡します。これにより、
ProductDetailView
から変更されたvalue1
の値がProductCategoryView
に戻り、selectedValue
として表示されます。これで、詳細ビューから元のビューに値を戻すことができます。