web-dev-qa-db-fra.com

@Binding et ForEach dans SwiftUI

Je ne peux pas comprendre comment utiliser @Binding en combinaison avec ForEach dans SwiftUI. Disons que je veux créer une liste de Toggles à partir d'un tableau de booléens.

struct ContentView: View {
    @State private var boolArr = [false, false, true, true, false]

    var body: some View {
        List {
            ForEach(boolArr, id: \.self) { boolVal in
                Toggle(isOn: $boolVal) {
                    Text("Is \(boolVal ? "On":"Off")")
                }                
            }
        }
    }
}

Je ne sais pas comment passer une liaison aux bools à l'intérieur du tableau à chaque Toggle. Le code ci-dessus donne cette erreur:

Utilisation de l'identifiant non résolu '$ boolVal'

Et ok, ça me va (bien sûr). J'ai essayé:

struct ContentView: View {
    @State private var boolArr = [false, false, true, true, false]

    var body: some View {
        List {
            ForEach($boolArr, id: \.self) { boolVal in
                Toggle(isOn: boolVal) {
                    Text("Is \(boolVal ? "On":"Off")")
                }                
            }
        }
    }
} 

Cette fois, l'erreur est:

Le référencement de l'initialiseur 'init (_: id: content :)' sur 'ForEach' nécessite que 'Binding' soit conforme à 'Hashable'

Existe-t-il un moyen de résoudre ce problème?

14
superpuccio

Si vous devez également modifier le nombre de Toggles (pas seulement leurs valeurs), considérez ceci. BTW, nous pouvons omettre le bloc ForEach {}.

struct ContentView: View {
   @State var boolArr = [false, false, true, true, false]

    var body: some View {
        NavigationView {
            // id: \.self is obligatory if you need to insert
            List(boolArr.indices, id: \.self) { idx in
                    Toggle(isOn: self.$boolArr[idx]) {
                        Text(self.boolArr[idx] ? "ON":"OFF")
                }
            }
            .navigationBarItems(leading:
                Button(action: { self.boolArr.append(true) })
                { Text("Add") }
                , trailing:
                Button(action: { self.boolArr.removeAll() })
                { Text("Remove") })
        }
    }
}
0
Paul B