Working with MVVM in SwifUI. My aim is to have an enum state property in the ViewModel so the View could adjust it self according to the state property. States could be: idle, busy, done and error. On done I want to navigate to another screen using NavigationLink, however the problem is that it is expecting a Binding<Bool> and I could not figure out a way to map my enum state to bool.
Here is the simplified code:
struct LoginView: View {
@ObservedObject private var viewModel: LoginViewModel
@ViewBuilder
var body: some View {
...
// success state
NavigationLink(destination: HomeFactory().make(), isActive: self.$viewModel.state /* <---- some sort of mapping should come here */){ EmptyView() }
...
}
}
Hope that I am missing something really basic and it could be easily achieved in an elegant way.
EDIT:
Seems like it should be possible with the next method:
NavigationLink(destination: HomeFactory().make(), tag: .done, selection: self.$viewModel.viewState, label: { EmptyView() })
However I get an error and I can't figure out what is wrong: Cannot convert value of type 'Binding<ViewState>' to expected argument type 'Binding<_?>'
Here is the code:
final class LoginViewModel: ObservableObject {
@Published var viewState: ViewState = .idle
func begin() {
..
self.viewState = .done
..
}
}
struct LoginView: View {
@ObservedObject private var viewModel: LoginViewModel
@ViewBuilder
var body: some View {
..
NavigationLink(destination: HomeFactory().make(), tag: .done, selection: self.$viewModel.viewState, label: { EmptyView() })
..
}
UPDATE:
I was very close. The ViewState in the vm should be optional:
@Published var viewState: ViewState? = .idle