I am trying to make a view where once a user pressed a button, 5 circles (lights) will turn on one after another. However, when the model changes the status of the light, the view doesn't update to represent each lights status.
View
struct ReactionLightsView: View {
@ObservedObject var viewModel: ReactionLightsViewModel
var body: some View {
VStack {
VStack(spacing: 0) {
HStack {
ForEach(viewModel.lights) { light in
Circle()
.foregroundColor(light.color)
}
}
} .padding()
Button(action: viewModel.start ) {
Text("Start")
}
}
}
}
ViewModel
class ReactionLightsViewModel: ObservableObject {
@Published private var model: ReactionLightsModel
init(){
model = ReactionLightsModel()
}
var lights: [Light] {
model.lights
}
func start() {
model.startTest()
}
}
Model
struct ReactionLightsModel {
private(set) var lights: [Light] = [Light(), Light(), Light(), Light(), Light()]
private(set) var start: UInt64?
private(set) var stop: UInt64?
private(set) var reactionTimeNanoseconds: UInt64?
mutating func startTest() {
print("start reaction test")
for i in 0..<5 {
lights[i].turnOn();
sleep(1)
}
for i in 0..<5 {
lights[i].turnOff()
}
start = DispatchTime.now().rawValue
print("done with reaction test")
}
mutating func stopTest() {
stop = DispatchTime.now().rawValue
reactionTimeNanoseconds = (stop! - start!)
print(reactionTimeNanoseconds)
}
}
Initially, I had the lights as an array of Booleans, with this implementation the lights would turn red (on) but only all at once once the 5 seconds had elapsed. However, not I changed each light to be its own object and the view does not update at all.
Lights
struct Light: Identifiable {
private(set) var isLit: Bool = false
private(set) var color: Color = .gray
let id = UUID()
mutating func turnOn() {
isLit = true
color = .red
}
mutating func turnOff() {
isLit = false
color = .gray
}
}
Would appreciate any advice on how to fix this and any other recommendations on how I can improve my code.
@Published private var model: ReactionLightsModel? Shouldn't that be@Published var model: ReactionLightsModel, or am I mistaken?