When I try to set show a toggle inside a loop of value from a dictionary, I get very little help from the error message.
If I un-comment the 3 lines of commented code below, trying to add a toggle for each of the properties in the loop, I get the following error:
Cannot convert value of type 'HStack, Text, ConditionalContent)>>' to closure result type '_'
import SwiftUI
struct properties {
var id : Int
var property : String
var isOn : Bool
}
struct ContentView: View {
@State var propertyValues: [properties] = [properties(id: 1, property: "DemoData", isOn: true),
properties(id: 2, property: "ShowLocalEvents", isOn: false)]
var body: some View {
NavigationView {
VStack {
List {
ForEach(propertyValues.identified(by: \.id)) { propertyValue in
HStack {
// Toggle(isOn: propertyValue.isOn) {
// Text("")
// }
Text("\(propertyValue.property)")
if propertyValue.isOn {
Text("On")
} else {
Text("Off")
}
}
}
}
}
}
}
}
The issue here is that the initializer Toggle(isOn:label:)
takes a Binding<Bool>
for its isOn
parameter rather than just a Bool
. A Binding<_>
is sort of a readable-writable "view" into a property that allows a control to update a value that it doesn't own and have those changes propagate out to whoever does own the property.
EDIT: I made this more complicated than it needed to be. The following works:
ForEach($propertyValues.identified(by: \.id.value)) { (propertyValue: Binding<properties>) in
HStack {
Toggle(isOn: propertyValue.isOn) {
Text("")
}
// ...
}
}
By using a $propertyValues
, we are accessing a Binding
to the array itself, which is transformed into bindings to each of the elements.
EDIT:
For the above to work, you'll need to add .value
in a couple places in the body so that you are referring to the actual values and not the bindings to the values.