Reputation: 81
I am working with SwiftUI. I have a global variable of a viewModel
that has a completion. I am trying to find a way to call a method in this class to perfume an action.
struct ContentView: View {
let viewModel = TimerViewModel(totalTime: 15, finished: {
print("I need it to call a method here")
})
I have tried having it optional then setting it in init but still get this error:
Escaping closure captures mutating 'self' parameter
I hope you can help.
Upvotes: 1
Views: 768
Reputation: 257749
Here is possible approach.
struct ContentView: View {
var viewModel: TimerViewModel? = nil // needs to be initialized
init() {
// assign function directly instead of via capturing closure
viewModel = TimerViewModel(totalTime: 15, finished: timerCallback)
}
var body: some View {
Text("Demo")
}
private func timerCallback() {
// do anything needed here
}
}
Upvotes: 1
Reputation: 54516
You get an error because you try to modify the ContentView
from inside the TimerViewModel
.
An alternative to calling a completion method can be to create a @Published
property in the TimerViewModel
:
class TimerViewModel: ObservableObject {
@Published var finished = false // it can be Bool or anything you want to pass to your View
func end() {
finished = true
}
}
And capture its change in the View
:
struct ContentView: View {
@ObservedObject var viewModel = TimerViewModel()
var body: some View {
VStack {
Text("Text")
}
.onReceive(viewModel.$finished) { finished in
if finished {
// timer has finished, you can call some method now
}
}
}
}
Upvotes: 3