ios 如何在SwiftUI中的多个视图之间传递Child视图的值?

w1jd8yoj  于 2023-05-23  发布在  iOS
关注(0)|答案(1)|浏览(162)

在我的项目中,我需要一个“产品”的ID打印到控制台,当我点击一个按钮。我在我的一个子视图中访问产品的“id”并将其打印到控制台(当在子视图中点击它时)。我需要在不同视图中的按钮中使用此ID。我该怎么做?以下是视图的结构:

struct IntroView: View {
    var body: some View {
        VStack {
            CustomSelectView()
            Button("Continue") {
                //Here is where the 'selectedProduct' data in ProductRowViewOnboard() needs to be accessed
            }
        }
    }
}
struct CustomSelectView: View {
    @State private var showingProductSheet = false
    var body: some View {
        HStack {
            VStack {
                Text("Select Product 1")
            }
            .onTapGesture {
                print("Select Product 1 Tapped...")
                showingProductSheet.toggle()
            }
            .sheet(isPresented: $showingProductSheet) {
                ProductSheetOnboard()
            }
            VStack {
                Text("Select Product 2")
            }
            .onTapGesture {
                print("Select Product 2 Tapped...")
                showingProductSheet.toggle()
            }
            .sheet(isPresented: $showingProductSheet) {
                ProductSheetOnboard()
            }
        }
    }
}
struct ProductSheetOnboard: View {
    @Environment(\.dismiss) var dismiss
    @StateObject var marketplaceModel = MarketplaceViewModel()
    let product_id: String
    var body: some View {
        var columns = Array(repeating: GridItem(.flexible()), count: 2)
        let defaults = UserDefaults.standard
        let keyString = defaults.string(forKey: "key") ?? ""
        ScrollView(.vertical, showsIndicators: false) {
            VStack {
                    ForEach(marketplaceModel.filteredProduct, id:\.self){ product in
                        ProductRowViewOnboard(productData: product,  product_id: product_id ?? "")
                    }
            }
        }
        .onAppear {
            let defaults = UserDefaults.standard
            let keyString = defaults.string(forKey: "key") ?? ""
            self.marketplaceModel.fetchProductTags(key: keyString ?? "")
            self.marketplaceModel.fetchMarketProducts(key: keyString ?? "")
        }
    }
}

struct ProductRowViewOnboard: View {
    @Environment(\.dismiss) var dismiss
    @State var selectedProduct : ProductTile?
    var productData: ProductRow
    let product_id: String
    var body: some View {
        HStack {
            ScrollView {
                HStack {
                    ForEach(productData.products ?? []) { product in
                        ProductView(productData: product)
                            .onTapGesture {
                                selectedProduct = product
//The following print statement works 
                                print("Product id: \(selectedProduct?.id ?? "")")
                                let defaults = UserDefaults.standard
                                let keyString: String? = defaults.string(forKey: "key") ?? ""
                                // The data in selectedProduct here needs to be accessed in IntroView()
                            }
                    }
                }
            }
        }
    }
}

在我在.onTapGesture{}中提供的最后一个视图(ProductRowViewOnboard)中,我已经指控了产品的id。我需要在IntroView()中访问此值,以便在Button中使用它。
我好像做不到。

dxpyg8gm

dxpyg8gm1#

您需要先将状态上移到需要的位置,然后向下传递let以进行读访问,或向下传递@Binding var以进行读/写访问,例如:

struct IntroView: View {
    @State var selectedProduct : ProductTile?

    var body: some View {
        ... 
        ProductRowViewOnboard(selectedProduct: $selectedProduct)
        ...
    }
}

struct ProductRowViewOnboard: View {
    @Binding var selectedProduct : ProductTile?
}

同样在SwiftUI中,View结构应该是视图数据的主要封装。不要使用视图模型对象,因为在获取其他视图数据时会遇到麻烦(就像您对onAppear的非标准使用所经历的那样);你也会遇到一致性错误,SwiftUI为View结构体使用值类型就是为了消除这些错误。

相关问题