【问题标题】:Updated @Published vars from Pickers won't pass their new values to Button function来自 Pickers 的更新的 @Published 变量不会将它们的新值传递给 Button 函数
【发布时间】:2021-06-22 14:50:33
【问题描述】:

我有一个异步函数,它执行 SQL 查询并更新 @Published 变量。我可以将这些新值作为 Picker 的默认值读入 Picker,但是当我更改 Picker 值 - 然后将其传递给另一个运行 SQL 更新函数(通过按钮)的函数时,它只会传递原始默认的 @Published 值,而不是用户与 Picker 交互选择的更新。 findSingleProduct 函数是通过将来自使用用户输入的前一个视图的条形码传递给它来调用的。

class ProductsModel: ObservableObject{

    @Published var Comp1Mat: Int = 0
    @Published var code: String = ""

    func findSingleProduct(code: String){
        // Completes an SQL query on the Products database to find a product by it's barcode number.
        // prepare json data
        let insertProductURL = URL(string: "http://recyclingmadesimple.xyz/service.php")!
        var urlRequest = URLRequest(url: insertProductURL)
        urlRequest.httpMethod = "POST"
    
        let postString = "code=\(code)"
        urlRequest.httpBody = postString.data(using: String.Encoding.utf8)
        
        let task = URLSession.shared.dataTask(with: urlRequest) { data, response, error in
            guard let data = data, error == nil else {
                print(error?.localizedDescription ?? "No data")
                return
            }
            let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
            if let responseJSON = responseJSON as? [String: Any] {
                DispatchQueue.main.async {
                    self.Comp1Mat = responseJSON["Comp1Mat"] as! Int
                }
            }
        }
        task.resume()
    }

这是我的视图,显示有关对象的选取器。我已经删除了很多 Picker,因为他们都遇到了同样的问题,所以解决方案应该是可以转移的。

struct ProductDetail: View {
    
        @ObservedObject private var viewModel = ProductsModel()
        init(ad: [String], material: [String], code: String){
            self.viewModel.findSingleProduct(code: code)
            
            }
    
        var body: some View {
    
            //This is the main stack that contains everything
            VStack(alignment: .leading){
    
                Picker(selection: $viewModel.Comp1Mat, label: Text("Material")){
                    ForEach(0 ..< material.count){
                        Text(self.material[$0])
                    }
                }

                Button(action: {viewModel.updateProduct(brands: "\(viewModel.Comp1Mat)", **Omitted variables for simplicity, they also run on similar Pickers**); showingAlert = true}, label: {
                    Text("Update Product")
                }).alert(isPresented: $showingAlert) {
                    Alert(title: Text("Product Updated"), message: Text("Thanks for helping the community!"), dismissButton: .default(Text("Dismiss")))
                }
}

我已经通过将一些值硬编码到按钮中来确认更新函数的 PHP 和 SQL 工作,例如:Button(action: {viewModel.updateProduct(Comp1Mat: "(5)"}...,它们确实被正确传递并更新了数据库。

我认为这个类似的问题可能有用,但我相信我已经正确使用了 $,这是为这个人建议的解决方案,所以我不确定为什么它对我不起作用。 Change a @Published var via Picker

谢谢。

【问题讨论】:

  • 尝试添加标签``` Text(self.material[$0]).tag($0)```
  • 我相信这已经奏效了,谢谢。我会将它添加到我的其他选择器中以检查它不会导致任何奇怪的问题,但如果没有,我会回来并标记你,以便你可以将其添加为答案,以便我可以接受它。 :)
  • @RajaKishan 这非常有效,谢谢。请您将其添加为答案。

标签: ios swift swiftui


【解决方案1】:

你只需要添加一个标签。

Text(self.material[$0]).tag($0)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-13
    • 2015-03-19
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    • 2021-05-31
    • 1970-01-01
    • 2020-10-18
    相关资源
    最近更新 更多