1
votes

SwiftUI Picker avec sélection comme struct

J'essaye d'utiliser Picker comme sélection de struct. Disons que j'ai une structure "Pet" comme ci-dessous

Picker("Pet", selection: $petSelection) {
ForEach(0 ..< Self.pet.count) { index in
    Text(Self.pet[index].name).tag(index)
    }

Je reçois tous les animaux d'une classe, où les animaux sont définis comme @Published var pets = Pet

Picker("Pet", selection: $petSelection){
                    ForEach(Self.pets) { item in
                        Text(item.name)

                    }
                }

Je voudrais pouvoir écrire une sélection du sélecteur à la variable ci-dessous:

@State private var petSelection: Pet?

Le sélecteur est:

static let pets = Class().pets

Le sélecteur montre correctement tous les familiers disponibles, mais lorsque j'ai choisi un animal, la sélection n'a pas été modifiée (néant). Comment dois-je le gérer?

Merci!

Éditer:

Bien sûr, je sais que je peux utiliser des balises comme ci-dessous:

struct Pet: Identifiable, Codable, Hashable {

    let id = UUID()
    let name: String
    let age: Int
}

Mais je me demande s'il est possible d'utiliser struct comme sélection. Merci


0 commentaires

3 Réponses :


1
votes

Vous utilisez la manière suivante:

 @Published var  pets: [Pet?] = [ nil, Pet(name: "123", age: 23), Pet(name: "123dd", age: 243),]

     VStack{
      Text(petSelection?.name ??  "name")
      Picker("Pet", selection: $petSelection){
         ForEach(Self.pets, id: \.self) { item in
            Text(item?.name ?? "name").tag(item)
       }}}


0 commentaires

0
votes

le type de $petSelection dans Picker(selection:[...] doit être le même type d' id dans votre structure. Donc, dans votre cas, vous devrez changer $petSelection pour taper si UUID puisque vos éléments dans la collection ont UUID comme identifiant.

Quoi qu'il en soit puisque ce n'est pas ce que vous recherchez, mais votre intention est de recevoir l' Pet dans son ensemble lorsqu'il est sélectionné. Pour cela, vous aurez besoin d'un wrapper contenant Pet comme id . Comme l' Pet est déjà Identifiable , il n'y a que quelques ajustements à faire:

Créer un wrapper ayant Pet comme id

Picker("Pet", selection: $petSelection) {
    ForEach(Self.pets.map(PetPickerItem.init), id: \.pet) {
        Text("\($0.pet?.name ?? "None")")
    }
}

Emballez maintenant tous les éléments de la collection dans l'élément de sélection

struct PetPickerItem {
    let pet: Pet?
}

Vous pouvez maintenant faire des ajustements mineurs comme rendre PetPickerItem identifiable pour supprimer le paramètre id: de ForEach .

C'est la meilleure solution que j'ai trouvée.


0 commentaires

0
votes

Voici comment je fais:

struct Language: Identifiable, Hashable  {
    var title: String
    var id: String
}


struct PickerView: View {

     var languages: [Language] = [Language(title: "English", id: "en-US"), Language(title: "German", id: "de-DE"), Language(title: "Korean", id: "ko-KR")]
     @State private var selectedLanguage = Language(title: "German", id: "de-DE")

     var body: some View {
        Picker(selection: $selectedLanguage, label: Text("Front Description")) {
            ForEach(self.languages, id: \.self) {language in
                Text(language.title)
           }
       }

}


0 commentaires