如何在SwiftUI中跨多视图传递子视图的Product id值?
解决SwiftUI中跨视图传递选中Product ID的问题
要实现从ProductRowViewOnboard将选中的Product ID传递到IntroView的「Continue」按钮逻辑中,最清晰的方式是使用共享ObservableObject作为状态管理容器,让所有相关视图共享同一状态实例。以下是具体修改步骤:
1. 创建共享状态ViewModel
定义一个ObservableObject类,用来存储选中的Product ID:
class SelectedProductViewModel: ObservableObject { @Published var selectedProductId: String? }
2. 在顶层视图初始化ViewModel
修改IntroView,初始化ViewModel并传递给子视图,同时在按钮点击时读取选中的ID:
struct IntroView: View { @StateObject private var selectedProductVM = SelectedProductViewModel() var body: some View { VStack { CustomSelectView(selectedProductVM: selectedProductVM) Button("Continue") { if let id = selectedProductVM.selectedProductId { print("选中的Product ID:\(id)") } else { print("未选中任何Product") } } } } }
3. 向下传递ViewModel到子视图
修改CustomSelectView,接收ViewModel并传递给弹出的ProductSheetOnboard:
struct CustomSelectView: View { @State private var showingProductSheet = false var selectedProductVM: SelectedProductViewModel var body: some View { HStack { VStack { Text("Select Product 1") } .onTapGesture { print("Select Product 1 Tapped...") showingProductSheet.toggle() } .sheet(isPresented: $showingProductSheet) { // 注意:需传入对应product_id值,示例中用占位符代替 ProductSheetOnboard(selectedProductVM: selectedProductVM, product_id: "product1_id") } VStack { Text("Select Product 2") } .onTapGesture { print("Select Product 2 Tapped...") showingProductSheet.toggle() } .sheet(isPresented: $showingProductSheet) { ProductSheetOnboard(selectedProductVM: selectedProductVM, product_id: "product2_id") } } } }
4. 在ProductSheetOnboard中传递ViewModel
修改ProductSheetOnboard,接收ViewModel并传递给ProductRowViewOnboard:
struct ProductSheetOnboard: View { @Environment(\.dismiss) var dismiss @StateObject var marketplaceModel = MarketplaceViewModel() var selectedProductVM: SelectedProductViewModel let product_id: String var body: some View { ScrollView(.vertical, showsIndicators: false) { VStack { ForEach(marketplaceModel.filteredProduct, id:\.self){ product in ProductRowViewOnboard( productData: product, product_id: product_id, selectedProductVM: selectedProductVM ) } } } .onAppear { let defaults = UserDefaults.standard let keyString = defaults.string(forKey: "key") ?? "" marketplaceModel.fetchProductTags(key: keyString) marketplaceModel.fetchMarketProducts(key: keyString) } } }
5. 在底层视图更新选中状态
修改ProductRowViewOnboard,接收ViewModel并在点击Product时更新选中ID:
struct ProductRowViewOnboard: View { @Environment(\.dismiss) var dismiss var productData: ProductRow let product_id: String var selectedProductVM: SelectedProductViewModel var body: some View { HStack { ScrollView { HStack { ForEach(productData.products ?? []) { product in ProductView(productData: product) .onTapGesture { let productId = product.id ?? "" print("Product id: \(productId)") // 更新共享状态中的选中ID selectedProductVM.selectedProductId = productId // 可选:选中后自动关闭弹窗 dismiss() } } } } } } }
原理说明
通过ObservableObject的@Published属性,当底层视图修改selectedProductId时,所有引用该ViewModel的视图都会收到状态更新通知。IntroView中的「Continue」按钮就能直接读取最新的选中ID,实现跨视图的数据传递。
内容的提问来源于stack exchange,提问作者Mxyb
相关产品推荐
相关产品推荐

