使用 SwiftUI 成功登录后导航
Posted
技术标签:
【中文标题】使用 SwiftUI 成功登录后导航【英文标题】:Navigate after successful login with SwiftUI 【发布时间】:2021-05-05 02:29:22 【问题描述】:我正在使用 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!")
【问题讨论】:
您应该在模型中创建某种“登录”状态,然后在您的根视图中,您可以根据该状态显示登录表单或登录视图。确保您的登录表单在用户成功登录后更新登录状态。 如果下一个视图是你的根视图,那么你可以试试这样, UIApplication.shared.keyWindow!.rootViewController = UIHostingController(rootView:如果您不想处理NavigationLink
,正如cmets 中提到的@Paulw11,您可以根据您在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!")
如果我是你,我也可以考虑使用authStateListener
并基于此设置登录属性。这样,如果重新打开应用并且用户仍处于登录状态,他们将自动转换到登录页面。
【讨论】:
感谢您的回答!是的,我确实尝试过,但我遇到的问题是,如果我将所有视图作为单独的 SwiftUI 文件,例如,登录视图作为单独的文件。然后,如果我登录并单击登录按钮,它不会重定向。我已附上更新后的代码以显示这一点。 您正在创建新的/不同的 LoginViewModel 实例——您需要在视图之间传递相同的实例。看看我的例子是怎么发生的? 哦,拍!谢谢!现在我也更好地理解了 StateObject、ObservableObject 和 ObservedObject!以上是关于使用 SwiftUI 成功登录后导航的主要内容,如果未能解决你的问题,请参考以下文章
swiftUI:登录完成后导航到主屏幕。通过按钮单击导航视图
SwiftUI NavigationLink:成功运行帐户创建代码后导航到目标视图