在我看来,Apple鼓励我们放弃UIViewController
在SwiftUI中使用,但如果不使用视图控件,我会觉得有些无能为力。我想要的是能够实现某种ViewModel
将事件发送给的功能View
。
ViewModel:
public protocol LoginViewModel: ViewModel {
var onError: PassthroughSubject<Error, Never> { get }
var onSuccessLogin: PassthroughSubject<Void, Never> { get }
}
Run Code Online (Sandbox Code Playgroud)
查看:
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
}
}
Run Code Online (Sandbox Code Playgroud)
使用SwiftUI,我不知道如何实现以下功能:
此外,对于任何关于如何以更好的方式实现我想要的东西的建议,我也将不胜感激。谢谢。
更新1:我能够显示警报,但仍然找不到如何在viewModel的回调中推送另一个视图
Boh*_*ych 11
我找到了答案。如果要显示回调的其他视图,则应
1)创建状态 @State var pushActive = false
2)当ViewModel通知登录成功时,将其设置pushActive
为true
func handleSuccessfullLogin() {
self.pushActive = true
print("handleSuccessfullLogin")
}
Run Code Online (Sandbox Code Playgroud)
3)创建隐藏NavigationLink
并绑定到该状态
NavigationLink(destination: ProfileView(viewModel: ProfileViewModelImpl()), isActive: self.pushActive) {
Text("")
}.hidden()
Run Code Online (Sandbox Code Playgroud)
我在这里添加了一些片段,因为我认为它简化了一些事情并使重用导航链接更容易:
1. 添加视图导航扩展
extension View {
func navigatePush(whenTrue toggle: Binding<Bool>) -> some View {
NavigationLink(
destination: self,
isActive: toggle
) { EmptyView() }
}
func navigatePush<H: Hashable>(when binding: Binding<H>,
matches: H) -> some View {
NavigationLink(
destination: self,
tag: matches,
selection: Binding<H?>(binding)
) { EmptyView() }
}
func navigatePush<H: Hashable>(when binding: Binding<H?>,
matches: H) -> some View {
NavigationLink(
destination: self,
tag: matches,
selection: binding
) { EmptyView() }
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以调用任何视图(确保它们(或父视图)在导航视图中)
2. 闲暇时使用
struct Example: View {
@State var toggle = false
@State var tag = 0
var body: some View {
NavigationView {
VStack(alignment: .center, spacing: 24) {
Text("toggle pushed me")
.navigatePush(whenTrue: $toggle)
Text("tag pushed me (2)")
.navigatePush(when: $tag, matches: 2)
Text("tag pushed me (4)")
.navigatePush(when: $tag, matches: 4)
Button("toggle") {
self.toggle = true
}
Button("set tag 2") {
self.tag = 2
}
Button("set tag 4") {
self.tag = 4
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
894 次 |
最近记录: |