Reputation: 450
I have a simple use case of having a VStack of a dynamic number of Text with Toggle buttons coming from an array.
import SwiftUI
public struct Test: View {
@ObservedObject public var viewModel = TestViewModel()
public init() {
}
public var body: some View {
VStack {
ForEach(viewModel.models) { model in
ToggleView(title: <#T##Binding<String>#>, switchState: <#T##Binding<Bool>#>)
//how to add the above
}
}.padding(50)
}
}
struct ToggleView: View {
@Binding var title: String
@Binding var switchState: Bool
var body: some View {
VStack {
Toggle(isOn: $switchState) {
Text(title)
}
}
}
}
public class TestModel: Identifiable {
@Published var state: Bool {
didSet {
//do something
//publish to the view that the state has changed
}
}
@Published var title: String
init(state: Bool, title: String) {
self.state = state
self.title = title
}
}
public class TestViewModel: ObservableObject {
@Published var models: [TestModel] = [TestModel(state: false, title: "Title 1"), TestModel(state: true, title: "Title 2")]
}
The following questions arise:
class ViewModel {
@Published var dataModel: [TestModel]
@Published var toggleStates = [Bool]() {
didSet {
//do something based on which element of the toggle states array has changed
}
}
}
Please help with the above questions.
Upvotes: 2
Views: 1148
Reputation: 1133
One way you could achieve what you desire is to use the binding power of @ObservedObject
.
The trick is to use indexes to reach the array elements for you binding.
If you loop on the array elements model
directly you loose the underlying binding properties.
struct Test: View {
@ObservedObject public var viewModel = TestViewModel()
var body: some View {
VStack {
ForEach(viewModel.models.indices) { index in
ToggleView(title: self.viewModel.models[index].title, switchState: self.$viewModel.models[index].state)
}
}.padding(50)
}
}
class TestViewModel: ObservableObject {
@Published var models: [TestModel] = [
TestModel(state: false, title: "Title 1"),
TestModel(state: true, title: "Title 2")]
}
struct ToggleView: View {
var title: String
@Binding var switchState: Bool
var body: some View {
VStack {
Toggle(isOn: $switchState) {
Text(title)
}
}
}
}
class TestModel: Identifiable {
var state: Bool
var title: String
init(state: Bool, title: String) {
self.title = title
self.state = state
}
}
Hope this does the trick for you.
Best
Upvotes: 2