在我看来,苹果正在鼓励我们放弃在SwiftUI中使用UIViewController,但如果不使用视图控制器,我觉得有点无能为力.我希望能够实现某种ViewModel,它将向View发送事件.

ViewModel:

public protocol LoginViewModel: ViewModel {
  var onError: PassthroughSubject<Error, Never> { get }
  var onSuccessLogin: PassthroughSubject<Void, Never> { get }
}

View:

public struct LoginView: View {
  fileprivate let viewModel: LoginViewModel
  
  public init(viewModel: LoginViewModel) {
    self.viewModel = viewModel
  }
  
  public var body: some View {
    NavigationView {
      MasterView()
        .onReceive(self.viewModel.onError, perform: self.handleError)
        .onReceive(self.viewModel.onSuccessLogin, perform: self.handleSuccessfullLogin)
    }
  }

  func handleSuccessfullLogin() {
    //push next screen
  }
  
  func handleError(_ error: Error) {
    //show alert
  }
}

使用SwiftUI,如果登录成功,我不知道如何推送另一个控制器

此外,如果您能就如何更好地实现我的目标提出建议,我将不胜感激.谢谢.

推荐答案

我找到了答案.如果你想在回调中显示另一个视图,你应该

  1. 创建状态@State var pushActive = false

  2. 当ViewModel通知登录成功时,将pushActive设置为true

    func handleSuccessfullLogin() {
        self.pushActive = true
        print("handleSuccessfullLogin")
    }
    
  3. 创建隐藏NavigationLink并绑定到该状态

    NavigationLink(destination: 
       ProfileView(viewModel: ProfileViewModelImpl()),
       isActive: self.$pushActive) {
         EmptyView()
    }.hidden()
    

Swift相关问答推荐

在Swift中initt()完成后运行一个函数

Swift 5.10:无法从非隔离的deinit访问属性*,这是Swift 6中的错误''''

同步问题,发送Api Call之前未设置idToken

如何将泛型函数存储到变量中?

音频播放器无法播放URL音频(操作系统状态错误2003334207.)

插入/删除视图时的Swiftui动态过渡

字典下标或运算符,如果密钥不存在,则添加指定的默认&值是SWIFT?

解码器是否需要具有密钥的外部数据表示?

ClosedRange.Swift 中 Int 的索引?

为什么无法在 Swift 中使用AVFoundation扫描 QRCode

将 Encodable 扩展添加到 Swift 嵌套枚举

swift 是否遇到 Java 的 2gb 最大序列化大小问题?

如何使用 Swinject 注册符合 ObservableObject 的协议?

ZStack 中的 ProgressView 与 View 的行为不同

如何处理永远不会失败的 String.Encoding 初始化程序?

更改该函数的参数之一时,如何将这些 SwiftUI 异步任务合并到一个任务中以从函数中获得正确的结果

符合协议要求委托变量在 ios13 中可用

swift 3 错误:参数标签 '(_:)' 不匹配任何可用的重载

使用 Swift 在 iOS 8 中为应用程序图标添加徽章

使用 Swift 以编程方式自定义 UITableViewCell