You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 06:37:25