1

问题 = 在 log_Status = true 后视图没有改变

在用户登录后,我试图将用户带到不同的视图。我已经在我的项目中实现了 Sign in with Apple 和 Sign in with Google。对于这个问题,我将展示使用 Google 代码登录。

@AppStorage("log_Status") var log_Status = false

已设置到相应的文件中。

用户单击使用 google 登录按钮并登录后,如下所示:

// 处理登录...

func handleSignin() {
    
    // Google Sign in...
    
    guard let clientID = FirebaseApp.app()?.options.clientID else { return }
    
    // Create Google Sign In configuration object.
    let config = GIDConfiguration(clientID: clientID)
    
    GIDSignIn.sharedInstance.signIn(with: config, presenting: getRootViewController()) { [self] user, error in
        
        if let error = error {
            print(error.localizedDescription)
            
            return
        }
        
        guard
            let authentication = user?.authentication,
            let idToken = authentication.idToken
        else {
            return
        }
        
        let credential = GoogleAuthProvider.credential(withIDToken: idToken,
                                                       accessToken: authentication.accessToken)
        
        // Firebase Auth...
        
        Auth.auth().signIn(with: credential) { result, err in
            
            if let error = error {
                print(error.localizedDescription)
                return
            }
            
            //Displaying User Name...
            guard let user = result?.user else {
                return
            }
            
            print(user.displayName ?? "Success!")
            
            // Updating User as Logged in
            withAnimation {
                log_Status = true
            }
        }
    }
}

最后,创建了一个 If 语句,以便使用 var log_Status 将用户带到不同的视图。

struct AccountView: View {

    @AppStorage("log_Status") var log_Status = false

    var body: some View {
        
        if log_Status {
            
            ContentView()
            
            NavigationView {
                Button("Log Out") {
                    // Apple Loging out User...
                    DispatchQueue.global(qos: .background).async {
                        try? Auth.auth().signOut()
                    }
        
                    // Google Loging out User...
                    GIDSignIn.sharedInstance.signOut()
                    try? Auth.auth().signOut()
                    

                   // Updating log_status = true
                    withAnimation {
                        log_Status = false
        } else { 
            SignInScreenView()
        }
    }
}

如果有人知道为什么视图没有改变,或者我以错误的方式实现@AppStorage,请告诉我。

如果需要更多信息,请随时询问。任何帮助表示赞赏!

4

1 回答 1

0

对于任何对此有疑问的人。这是苹果告诉我的:

如果您需要在视图“外部”访问它,最好将 @AppStorage 放在视图层次结构中更高的位置并通过绑定传递它。

有两种方法可以使用 @AppStorage 属性包装器并在您的应用程序周围共享它 -

  1. 使用 @Bindings 围绕其他视图发送应用存储值。
  2. 使用“.environment”在其他视图周围发送应用存储值。

我更喜欢#2,因为它更易于使用且更灵活。这是 #2 的示例,它需要一个EnvironmentKey和 扩展名EnvironmentValues

struct CustomTextKey: EnvironmentKey {
    static var defaultValue: Binding<String> = >Binding.constant("Default Text")
}
extension EnvironmentValues {
    var customText: Binding<String> {
        get { self[CustomTextKey.self] }
        set { self[CustomTextKey.self] = newValue }
    }
}
struct ContentView: View {
    @AppStorage("text") private var text: String = ""
    
    var body: some View {
        TextEditor(text: $text).padding()
        Divider()
        SecondView()
            .environment(\.customText, $text)
    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
struct SecondView: View {
    var body: some View {
        ThirdView()
    }
}
struct ThirdView: View {
    @Environment(\.customText) private var text: Binding<String>
    var body: some View {
       TextEditor(text: text).padding()
   }
}

请记住,您@AppStorage仅在一个地方将您定义为唯一的事实来源,并相应地将其传递给其他视图。

我会尝试实施@Bindings,因为我发现它更容易。

于 2022-01-09T21:39:11.650 回答