Reputation: 63
@State private var isOn1 = false
@State private var isOn2 = false
var body: some View {
ScrollView{
Toggle("switch1",isOn:$isOn1)
Toggle("switch2",isOn:$isOn2)
}
Here is what I have so far. Is there a way for me to add an if statement when activating a toggle that all the other toggles will be off. Or is there anyway to change the states of the toggles when activating one. Any answers are appreciated thank you!
Upvotes: 6
Views: 2680
Reputation: 21
Here is a simpler solution and more practical example. Keep track of the active selection and create a binding that checks and sets the active selection
struct Item: Identifiable, Hashable {
var name: String
let id: UUID = .init()
}
struct ContentView: View {
@State var items: [Item] = [Item(name: "Item 1"),
Item(name: "Item 2"),
Item(name: "Item 3")]
@State var activeItem: Item?
var body: some View {
List(items) { item in
HStack {
Text(item.name)
let isOn = Binding<Bool>(get: { activeItem == item },
set: { _ in activeItem = item })
Toggle("", isOn: isOn)
}
}
.onAppear {
activeItem = items[0]
}
}
}
Upvotes: 0
Reputation: 257493
Here is some alternate approach, which does not require to hardcode interdependently all bindings, but instead use shared storage of bools:
struct DemoExclusiveToggles: View {
@State var flags = Array(repeating: false, count: 9)
var body: some View {
ScrollView {
ForEach(flags.indices) { i in
ToggleItem(storage: self.$flags, tag: i, label: "Switch \(i+1)")
.padding(.horizontal)
}
}
}
}
struct ToggleItem: View {
@Binding var storage: [Bool]
var tag: Int
var label: String = ""
var body: some View {
let isOn = Binding (get: { self.storage[self.tag] },
set: { value in
withAnimation {
self.storage = self.storage.enumerated().map { $0.0 == self.tag }
}
})
return Toggle(label, isOn: isOn)
}
}
Upvotes: 8
Reputation: 54706
You can define isOn2
as a Binding
. You can create a Binding
by passing in a closure for its getter and another one for its setter. For your isOn2
Binding
you'll simply need to return the negated value of isOn1
and in its setter, you'll set isOn1
to the negated value passed in to the setter.
struct ToggleView: View {
@State private var isOn1 = false
var body: some View {
let isOn2 = Binding<Bool>(
get: { !self.isOn1 },
set: { self.isOn1 = !$0 }
)
return ScrollView{
Toggle("switch1",isOn: $isOn1)
Toggle("switch2",isOn: isOn2)
}
}
}
Upvotes: 2