Estoy intentando seleccionar un número de cuenta predeterminado de una lista de cuentas disponibles. Los datos provienen de una selección de datos FMDB. He creado una vista de prueba con dos tipos de selectores. Uno que enumera las cuentas que he recuperado en una matriz de registros de datos que es una estructura rápida. El otro selector es el que proviene de un ejemplo en línea para seleccionar colores. El valor límite de "selección" de colores se actualiza como se esperaba, pero el valor límite de "selección" que establezco no cambia cuando se presenta y selecciona una de las dos cuentas. A continuación se muestra el código de mi vista de prueba que se compila y se ejecuta. Cuando selecciono el valor de la cuenta, que es [12345678] o [12345679], que aparecen como dos filas en el selector, el valor de vinculación de la selección no cambia. Pero para el valor de selección de colores, se actualiza. Estoy bastante confundido aquí ...

La estructura del registro de cuentas es:

    // 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
rpetruzz 13 mar. 2021 a las 22:24

2 respuestas

La mejor respuesta

Están sucediendo dos cosas:

  1. Necesita un .tag() en sus elementos Picker para decirle al sistema qué elemento pertenece a qué elemento:
Picker(selection: $selectedAccount, label: Text(""))
            {
                ForEach (self.acctRecords, id: \.self) { acct in
                    Text("\(acct.account_code!)").tag(acct.account_id)
                }
            }
  1. SwiftUI necesita que los tipos del parámetro selection y el tipo tag sean iguales. Debido a que en su modelo, account_id se define como Int! y no Int, su selectedAccount también debe ser 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", 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)
        }
    }
}
1
jnpdx 13 mar. 2021 a las 19:34

Intenta agregar .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
}
0
Joannes 14 mar. 2021 a las 08:00