选择器选择未更新

问题描述

我正在尝试从可用帐户列表中选择一个认帐号。数据来自 FMDB 数据选择。我创建了一个测试视图,其中包含两种类型的选择器。一个列出我检索到的数据记录数组的帐户,该数组是一个 swift 结构。另一个选择器来自一个在线示例,用于选择颜色。颜色“选择”绑定值按预期更新,但是当出现并选择两个帐户之一时,我设置的“选择”绑定值不会更改。下面是我的测试视图中编译和运行的代码。当我选择在选择器中显示为两行的 [12345678] 或 [12345679] 帐户值时,选择绑定值不会改变。但是对于颜色选择值,它会更新。我在这里很困惑...

账户记录的结构是:

    // Account record for FMDB
    struct AccountRecord: Hashable {
        var account_id: Int!
        var account_code: Int!
        var account_name: String!
        var running_balance: Double!
        var hidden_balance: Double!
        var actual_balance: Double!
    }
  import SwiftUI

  struct PickerTestView: View {
    
    @State private var selectedAccount = 0
    @State private var selectedColor = 0
    
    var acctRecords: [Accounts.AccountRecord] {
        return Accounts.shared.selectAllAccounts()
    }
    var colors = ["Red","Green","Blue","Tartan"]
    
    var body: some View {
        vstack{
            Picker(selection: $selectedAccount,label: Text(""))
            {
                ForEach (self.acctRecords,id: \.self) { acct in
                    Text("\(acct.account_code!)")
                }
            }
            
            Text("selectedAccount = \(selectedAccount)")
                .font(.largeTitle)
            
            Picker(selection: $selectedColor,label: Text("Please choose a color")) {
                ForEach(0 ..< colors.count) {
                    Text(self.colors[$0])
                }
            }
            
            Text("Selectedcolor = \(selectedColor)")
            Text("You selected \(colors[selectedColor])")
            
            
        }
    }
  }

  struct PickerTestView_Previews: PreviewProvider {
      static var previews: some View {
          PickerTestView()
      }
  }

解决方法

有两件事正在发生:

  1. 您需要在 .tag() 元素上使用 Picker 来告诉系统哪个元素属于哪个项目:
Picker(selection: $selectedAccount,label: Text(""))
            {
                ForEach (self.acctRecords,id: \.self) { acct in
                    Text("\(acct.account_code!)").tag(acct.account_id)
                }
            }
  1. SwiftUI 需要 selection 参数的类型和 tag 类型相同。因为在您的模型中,account_id 被定义为 Int! 而不是 Int,您的 selectedAccount 也需要是 Int!
@State private var selectedAccount : Int! = 0 

以下内容适用于嵌入的一些测试数据:
struct PickerTestView: View {
    @State private var selectedAccount : Int! = 1
    @State private var selectedColor = 0
    
    var acctRecords: [AccountRecord] {
        return [.init(account_id: 1,account_code: 1,account_name: "1",running_balance: 0,hidden_balance: 0,actual_balance: 0),.init(account_id: 2,account_code: 2,account_name: "2",.init(account_id: 3,account_code: 3,account_name: "3",actual_balance: 0)
        ]
    }
    var colors = ["Red","Green","Blue","Tartan"]
    
    var body: some View {
        VStack{
            Picker(selection: $selectedAccount,id: \.self) { acct in
                    Text("\(acct.account_code!)").tag(acct.account_id)
                }
            }
            Text("selectedAccount = \(selectedAccount)")
                .font(.largeTitle)
        }
    }
}
,

尝试添加.onChange

Picker(selection: $selectedAccount,label: Text("")) {
    ForEach (self.acctRecords,id: \.self) { acct in
        Text("\(acct.account_code!)").tag(acct.account_code) // <- add tag here
    }
}
.onChange(of: selectedAccount) {
    selectedAccount = $0
}