使用 SwiftUI 成功登录后导航

时间:2021-05-05 02:29:22

标签: ios swift firebase swiftui

我使用 Firebase 和 SwiftUI 以用户身份登录。我一切正常,但无法弄清楚用户成功登录后如何导航到下一页。 NavigationLinks 对我来说似乎很奇怪,所以我想知道是否还有其他方法可以导航到下一个视图。 LoginView 包含登录屏幕,LoginViewModel 使用 Firebase 执行登录过程。问题是,如果我根据根视图中的变量返回视图,一旦打开除根视图以外的任何视图,它就不会更改视图(即,如果我导航到登录视图,它不会转到按下登录按钮后的主视图)。

ContentView(显示所有其他视图的根视图):

import SwiftUI

struct ContentView: View {
    @StateObject var userLoggedIn = LoginViewModel()
    var body: some View {
        if !userLoggedIn.isLoggedIn {
            LoginView()
        }
        else {
            MainView()
        }
    }
}

登录视图:

import SwiftUI
import FirebaseAuth

struct LoginView: View {
    
    @State private var email: String = ""
    @State private var password: String = ""
    @State private var isEditing = false
    @State private var showPassword = false
    @State private var radius = 300
    
    private var canLogIn: Bool {
        return !email.isEmpty && !password.isEmpty
    }

    let loginView = LoginViewModel()
    
    @ViewBuilder
    var body: some View {
        
        return NavigationView(content: {
            
            VStack {
                Spacer()
                    .frame(height: 150)
                
                Text("PET SUPPORT").foregroundColor(Color.petSupportText)
                    .font(Font.custom("Permanent Marker", size: 36))
                    .padding()

                Group {
                    
                    HStack {
                        
                        Text("EMAIL")
                            .font(Font.custom("Permanent Marker", size: 18))
                            .padding(.top, 10)
                        
                        Spacer()
                        
                    }
                    
                    TextField("Email", text: $email) {
                        isEditing in self.isEditing = isEditing
                    }
                    .autocapitalization(.none)
                    .keyboardType(.emailAddress)
                    .disableAutocorrection(true)
                    .padding(.top, 20)
                    
                    Divider()
                        .foregroundColor(.black)
                    
                }

                
                Group {
                    
                    HStack {
                        
                        Text("PASSWORD")
                            .font(Font.custom("Permanent Marker", size: 18))
                            .padding(.top, 10)
                        
                        Spacer()
                        
                    }

                    ZStack {
                        if showPassword {
                            TextField("Password", text: $password)
                        }
                        else {
                            SecureField("Password", text: $password)
                        }
                    }
                    .frame(height: 20)
                    .autocapitalization(.none)
                    .overlay(Image(systemName: showPassword ? "eye.slash" : "eye").onTapGesture { showPassword.toggle() }, alignment: .trailing)
                    .disableAutocorrection(true)
                    .padding(.top, 20)
                    
                    Divider()
                        .foregroundColor(.black)
                    
                }
                
                Spacer();
                
                Group {
                    
                    Button(action: {
                            loginView.login(email: email, password: password)
                            radius = 2000
                            MainView()
                    }, label: {
                        Text("Login")
                    })
                        .foregroundColor(.white)
                        .font(Font.custom("Permanent Marker", size: 18.0))
                        .padding(.horizontal, 20)
                        .padding()
                        .background(Color.petSupportBlue)
                        .cornerRadius(70.0)
                        .disabled(!canLogIn)
                }
                
                Spacer()
            }
            .padding(.horizontal, 30)
            .ignoresSafeArea()
            
        })
        
    }
}

登录视图模型:

import Foundation
import Firebase

class LoginViewModel: ObservableObject {
    
    @Published var isLoggedIn = false
    func login(email: String, password: String) {
        
        Auth.auth().signIn(withEmail: email, password: password) { (result, error) in
            
            if let error = error {
                print(error.localizedDescription)
            } else {
                print("Logged In!")
                self.isLoggedIn = true
            }
        }
        
    }
    
}

主视图:

import SwiftUI

struct MainView: View {
    var body: some View {
        Text("Hello, World!")
    }
}

1 个答案:

答案 0 :(得分:3)

如果您不想处理 Fatal error: Uncaught Error: Call to undefined function create_function() in C:\xampp\htdocs\inoerp\www\includes\engine\install\steps\complete_install.php:78 Stack trace: #0 C:\xampp\htdocs\inoerp\www\includes\engine\install\steps\complete_install.php(20): getQueriesFromSQLFile('C:\\xampp\\htdocs...') #1 C:\xampp\htdocs\inoerp\www\includes\engine\install\steps\complete_install.php(115): importSQL('C:\\xampp\\htdocs...', Object(dbc)) #2 C:\xampp\htdocs\inoerp\www\includes\engine\install\install_template.php(40): require_once('C:\\xampp\\htdocs...') #3 C:\xampp\htdocs\inoerp\www\install.php(44): include_once('C:\\xampp\\htdocs...') #4 {main} thrown in C:\xampp\htdocs\inoerp\www\includes\engine\install\steps\complete_install.php on line 78 ,如评论中提到的@Paulw11,您可以根据您在 NavigationLink 上设置的属性有条件地显示登录/注销视图.您甚至可以添加动画/过渡。下面是一个简单的例子:

ObservableObject

如果我是你,我也可能会考虑使用 class LoginManager : ObservableObject { @Published var isLoggedIn = false func login() { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { withAnimation { self.isLoggedIn = true } } } } struct ContentView : View { @StateObject var loginManager = LoginManager() var body: some View { if loginManager.isLoggedIn { LoggedInView() .frame(maxWidth: .infinity, maxHeight: .infinity) .transition(.move(edge: .leading)) } else { LoginView(loginManager: loginManager) .frame(maxWidth: .infinity, maxHeight: .infinity) .transition(.move(edge: .leading)) } } } struct LoginView : View { @ObservedObject var loginManager : LoginManager var body: some View { Button("Login") { loginManager.login() } } } struct LoggedInView : View { var body: some View { Text("Logged in!") } } 并基于此设置登录属性。这样,如果应用程序重新打开并且用户仍处于登录状态,他们将自动转换到登录页面。