Swiftui 选择器选择未更新

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

我正在尝试从可用帐户列表中选择默认帐户号。数据来自FMDB数据选择。我创建了一个测试视图,其中包含两种类型的选择器。一个将我检索到的帐户列在数据记录数组中的列表,该数组是一个swift结构。另一个选择器来自在线示例,用于选择颜色。颜色“selection”绑定值按预期更新,但当显示并选择两个帐户之一时,我设置的“selection”绑定值不会更改。下面是我的测试视图中编译和运行的代码。当我选择在选择器中显示为两行的帐户值[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!
    }
导入快捷界面
结构选择器测试视图:视图{
@国家私有变量selectedAccount=0
@状态私有变量selectedColor=0
var账户记录:[账户.账户记录]{
返回帐户。共享。选择AllAccounts()
}
var colors=[“红色”、“绿色”、“蓝色”、“格子花纹”]
var body:一些观点{
VStack{
选择器(选择:$selectedAccount,标签:文本(“”))
{
ForEach(self.acctRecords,id:\.self){acct in
文本(\(账户\代码!))
}
}
文本(“selectedAccount=\(selectedAccount)”)
.font(.largeTitle)
选择器(选择:$selectedColor,标签:文本(“请选择颜色”)){
ForEach(0..<颜色数){
文本(self.colors[$0])
}
}
文本(“Selectedcolor=\(Selectedcolor)”)
文本(“您选择了\(颜色[selectedColor]))
}
}
}
结构选择器测试视图\u预览:PreviewProvider{
静态var预览:一些视图{
PickerTestView()
}
}

尝试添加
。一旦更改

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
}
Picker(选择:$selectedAccount,标签:Text(“”)){
ForEach(self.acctRecords,id:\.self){acct in

Text(“\(acct.account\u code!)”).tag(acct.account\u code)//发生了两件事:

  • 您需要在
    选择器
    元素上添加
    .tag()
    ,以告知系统哪个元素属于哪个项目:
  • SwiftUI需要
    选择
    参数和
    标记
    类型的类型相同。因为在您的模型中,
    帐户id
    被定义为
    Int!
    ,而不是
    Int
    ,所以您的
    所选帐户
    也需要是
    Int!

  • 以下内容适用于嵌入到中的一些测试数据:
    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", running_balance: 0, hidden_balance: 0, actual_balance: 0),
                    .init(account_id: 3, account_code: 3, account_name: "3", running_balance: 0, hidden_balance: 0, actual_balance: 0)
            ]
        }
        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!)").tag(acct.account_id)
                    }
                }
                Text("selectedAccount = \(selectedAccount)")
                    .font(.largeTitle)
            }
        }
    }
    

    哇,谢谢你花时间帮我看这个。我一直在寻找这个解决方案。我希望我能找到一个SwiftUI的来源来解释这样的东西。有一些关于如何做这些东西的例子,但没有人解释这些过程的细微差别。我最近读了《掌握Swift 5.3》作者Jon Hoffman,他在Swift语言方面帮了我很大的忙。我强烈推荐SwiftUI和他们的配套应用程序。非常好的资源。如果这个答案有用,请随意投票。您好,再次感谢您提醒我有关Swift-lab.com的事。实际上我已经购买了配套应用程序我忘记了。我打开应用程序,用Javier的选取器示例尝试,发现它们不起作用。我与Javier通信,他昨晚确认苹果改变了optionals的选取器行为。再次感谢……谢谢,是上面提到的标记,同时确保我的标记类型=绑定选择类型我没有解决我的问题。但是我添加了.onchange以获得一些文本来反映更改。
    Picker(selection: $selectedAccount, label: Text(""))
                {
                    ForEach (self.acctRecords, id: \.self) { acct in
                        Text("\(acct.account_code!)").tag(acct.account_id)
                    }
                }
    
    @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", running_balance: 0, hidden_balance: 0, actual_balance: 0),
                    .init(account_id: 3, account_code: 3, account_name: "3", running_balance: 0, hidden_balance: 0, actual_balance: 0)
            ]
        }
        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!)").tag(acct.account_id)
                    }
                }
                Text("selectedAccount = \(selectedAccount)")
                    .font(.largeTitle)
            }
        }
    }