在父 swiftui 视图中,我如何知道内部视图 viewmodel void 方法中的状态何时发生变化?
Posted
技术标签:
【中文标题】在父 swiftui 视图中,我如何知道内部视图 viewmodel void 方法中的状态何时发生变化?【英文标题】:In parent swiftui view how could I know when a state changes in an inner views viewmodel void method? 【发布时间】:2020-08-27 07:18:22 【问题描述】:给定一个 AuthenticationView swiftui 结构包含一个 UserLoginView。 UserLoginView 有一个 UserLoginViewModel 类用于处理登录按钮操作。
在 AuthenticationView 中,我想知道内部 UserLoginView 中变量的值何时发生变化(如果 AuthenticationView 中的 tutorialScreenIsShowable 为 true,则 NavigationLink 导航到下一张幻灯片)。
struct AuthenticationView: View
@State private var tutorialScreenIsShowable = false
var body: some View
NavigationView
ZStack
NavigationLink(destination: TutorialView(), isActive: $tutorialScreenIsShowable)
EmptyView()
UserLoginView(tutorialScreenIsShowable: self.$tutorialScreenIsShowable)
,
struct UserLoginView: View
@Binding var tutorialScreenIsShowable: Bool
@ObservedObject var userLoginViewModel = UserLoginViewModel()
var body: some View
Button(action:
self.userLoginViewModel.loginButtonAction() // it not works but I need this way
// self.tutorialScreenIsShowable = self.userLoginViewModel.loginButtonActionWithReturn() // it works, but its not good in this case
)
Text("Log in")
,
class UserLoginViewModel: NSObject, ObservableObject
@Published var tutorialScreenIsShowable = false
func loginButtonAction()
self.tutorialScreenIsShowable = true
func loginButtonActionWithReturn() -> Bool
return true
据我所知,该函数是否有一个可以工作的返回值,但在这种情况下,有一个委托方法正在运行,我可以在其中处理该变量。
我想尽可能避免使用@EnvironmentObject,我希望有另一种解决方案。
你能帮我解决这个问题吗?
编辑:我简化了示例。并在此处上传了一个示例项目:https://www.dropbox.com/s/paosp6iom9oks9p/InnerViewPropBind.zip
【问题讨论】:
【参考方案1】:这种行为起源于NavigationView
,在更新期间多次重新创建自己的内容。
这是一个可能的解决方案 - 一些重新设计和所有权更改。
使用 Xcode 11.4 / ios 13.4 测试
struct AuthenticationView: View
// keep model here to avoid recreation inside navigation view
@ObservedObject var userLoginViewModel = UserLoginViewModel()
var body: some View
NavigationView
ZStack
// use binding directly in view model
NavigationLink(destination: Text("TutorialView"), isActive: $userLoginViewModel.tutorialScreenIsShowable)
EmptyView()
UserLoginView(userLoginViewModel: userLoginViewModel)
struct UserLoginView: View
@ObservedObject var userLoginViewModel: UserLoginViewModel
var body: some View
Button(action:
self.userLoginViewModel.loginButtonAction()
)
Text("Log in")
class UserLoginViewModel: NSObject, ObservableObject
@Published var tutorialScreenIsShowable = false
func loginButtonAction()
self.tutorialScreenIsShowable = true
func loginButtonActionWithReturn() -> Bool
return true
【讨论】:
感谢您的建议,但不幸的是它不起作用。 ): NavigationLink 不会导航到下一张幻灯片。 嗯,导航是不同的问题。您无法在模态视图中导航,首先您必须关闭模态视图。 如果 loginWithGoogleButtonAction 有返回值 (self.tutorialScreenIsShowable = self.userLoginViewModel.loginWithGoogleButtonAction() ),则导航有效。所以这可能不是问题。否则,我也尝试通过属性控制视图的可见性,但它也没有改变。 是否收到didSignInFor
回调?在主队列上?如果第一次是,但第二次没有,则应将重定向添加到主调度队列。我无法测试您的 API 相关部分。
请再次查看示例,我清除了代码,现在没有api。我链接了我的示例项目。我希望它可以更清洁。谢谢!!以上是关于在父 swiftui 视图中,我如何知道内部视图 viewmodel void 方法中的状态何时发生变化?的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI 视图 onAppear 事件调用回扫手势动作