基于外部单例类中的属性的 SwiftUI 显示表

Posted

技术标签:

【中文标题】基于外部单例类中的属性的 SwiftUI 显示表【英文标题】:SwiftUI show sheet based on property in externals singleton class 【发布时间】:2021-08-10 20:49:34 【问题描述】:

我陷入 swiftui 并试图显示基于外部类中的属性的工作表。我希望根据此属性更新视图。据我了解,我需要使用带有 @Published 属性的 ObservableObject 。但是,我似乎无法让我的视图“观察”有问题的属性。我试过使用@ObservedObject、@State 和@EnvironmentObject。但这一切都会导致如下错误:

Cannot convert value of type 'Bool' to expected argument type 'Binding<Bool>'

视图类中.sheet 行下方的此错误

我的外部类如下所示:

class Authenticator: ObservableObject 
    @Published var isSignedIn: Bool = false
    
    static let shared = Authenticator()

     init() 
    handle = Auth.auth().addStateDidChangeListener([weak self] auth, user in
        if user != nil 
            self?.isSignedIn = true
            
         else 
            self?.isSignedIn = false
   
        
    )


    func signIn(email:String, password:String) 
          //signin
          isSignedIn = true;
    


//查看代码

struct AccountView: View 
    
    @ObservedObject var authenticator:Authenticator = Authenticator.shared
    var body: some View 
        NavigationView 
            ZStack 
                Color.white.edgesIgnoringSafeArea(.all).frame(maxWidth:.infinity, maxHeight: .infinity)
           
                if Authenticator.shared.isSignedIn 
                    Button 
                        //sign out here which then updates isSignedIn property
                        Authenticator.shared.signout() 
                     label: 
                        Text("Sign out")
                    

                

            .sheet(isPresented: !authenticator.isSignedIn) 
                
             content: 
                AuthenticationView()
            
          
        

    

我不确定是否因为我的 ObservableObject 是单例而出现问题?我的代码将登录,然后如果我重新启动应用程序,则会观察到登录状态。它当时似乎没有更新我的用户界面。

我的身份验证器是一个单例,因为我正在使用 Firebase 身份验证并尝试观察身份验证状态的变化。但我不知道这是否是错误的方法,以及我是否应该在我的App 中实例化我的身份验证器实例并将其作为@EnvironmentObject 传递。

任何帮助将不胜感激。

【问题讨论】:

Authenticator.shared 不会自行观察。它不会触发更新。在body 中使用authenticator。使用@ObservedObject@StateObject 包裹时完成观察 这是 .sheet 行不工作,它引用 authenticator 而不是 Authenticator.shared 如我的帖子中提到的那样 你怎么能观察到“认证状态变化”呢?如果身份验证基于不记名令牌,则如果访问令牌过期,用户将被“注销”。由于访问令牌是不透明的数据,客户端无法知道何时发生这种情况 - 您必须对受保护资源执行请求 - 然后返回适当的 HTTP 状态代码。或者您可能的意思是“已注册”? 我使用 firebase 身份验证处理程序通知我用户身份验证状态更改,然后相应地更新我的身份验证器变量。我已经编辑显示这个 谢谢你,这个问题和@Jake 引导我找到正确的解决方案! 【参考方案1】:

我相信就像将工作表代码修改为一样简单:

.sheet(isPresented: !$authenticator.isSignedIn) 
    AuthenticationView()

【讨论】:

$ 很重要。它引用 observable 对象并监听变化。 其实还有一点。我将链接到答案以允许您添加!在绑定布尔前面反转值***.com/a/61733134/9333764 感谢您的链接,我来晚了,所以早上会尝试从链接的答案中多读一点

以上是关于基于外部单例类中的属性的 SwiftUI 显示表的主要内容,如果未能解决你的问题,请参考以下文章

在打开的单例类中调用单例类方法

Java线程和多线程——单例类中的线程安全

php设计模式--单例模式

设计模式(创建型模式-单例模式)

PHP设计模式

单例模式的五种实现方法