是否可以在 SwiftUI 中将枚举“映射”到 Binding<Bool>?

EvZ*_*EvZ 5 ios swift swiftui

与工作MVVM在SwifUI。我的目标是拥有一个enum国家财产,ViewModel以便View可以根据国家财产自行调整。美国可能是:idlebusydoneerror。Ondone我想使用 导航到另一个屏幕NavigationLink,但问题是它期待 aBinding<Bool>并且我无法想出一种方法将我的枚举状态映射到 bool。

这是简化的代码:

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() }
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

希望我错过了一些非常基本的东西,并且可以以优雅的方式轻松实现。

编辑:

似乎应该可以使用下一个方法:
NavigationLink(destination: HomeFactory().make(), tag: .done, selection: self.$viewModel.viewState, label: { EmptyView() })

但是我收到一个错误,我无法弄清楚出了什么问题: Cannot convert value of type 'Binding<ViewState>' to expected argument type 'Binding<_?>'

这是代码:

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() })
    ..
  }
Run Code Online (Sandbox Code Playgroud)

更新:

我非常接近。将ViewState在虚拟机应该是选择性的:
@Published var viewState: ViewState? = .idle

Vla*_*lad 6

没有一种优雅的方法可以将其映射到视图中。
但是,LoginViewModel您可以在状态更新时设置一个 @Published 变量。

这是一个例子:

class LoginViewModel: ObservableObject {
    @Published var shouldNavigate = false  

    var state: State = .idle {
        didSet {
            self.shouldNavigate = state == .done
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将您的更改NavigationLink为:

NavigationLink(destination: HomeFactory().make(), isActive: self.$viewModel.shouldNavigate){ EmptyView() }
Run Code Online (Sandbox Code Playgroud)

编辑:
您可以使用 NavigationLink 根据状态或其他一些枚举进行导航,如下所示:

NavigationLink(destination: HomeFactory().make(), tag: State.done, selection: self.$state){ EmptyView() }
Run Code Online (Sandbox Code Playgroud)

并将您的虚拟机状态定义更新为:
@Published var state: State = .idle