使用 SwiftUI 成功登录后导航

2023-12-19

我正在使用 Firebase 和 SwiftUI 以用户身份登录。我一切正常,但无法弄清楚用户成功登录后如何导航到下一页。导航链接对我来说似乎很奇怪,所以我想知道是否有其他方法可以导航到下一个视图。这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!")
    }
}

如果你不想处理NavigationLink正如 @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!")
    }
}

如果我是你,我也可能会考虑使用 atauthStateListener并据此设置登录属性。这样,如果重新打开应用程序并且用户仍处于登录状态,他们将自动转换到登录页面。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 SwiftUI 成功登录后导航 的相关文章

随机推荐

  • 如何获取html页面上特定部分的背景颜色

    我使用渐变来设置 html 正文背景的颜色 CSS background linear gradient to top fb4080 10 ebb523 22 58d27c 40 2aff00 52 0fd2b7 65 6b6dff 80
  • Android 语音识别命令

    Goal 语音识别开始 说出语音命令并完成正确的操作 播放一些音乐会启动音乐播放器播放任何应该发生的事情 现在的情况 我正在运行一个测试应用程序 它启动 Android 语音识别 成功监听并将结果返回到我的 Activity 启动语音识别的
  • 什么是haslayout?

    我读过一些关于它的文章 但没有明白到底是什么 有人可以解释一下吗 是不是只和IE6有关 什么是zoom 1 Is layout是只有 IE 的 TAG 吗 Edit 我发现此信息对我来说非常有用 因为 Internet Explorer 太
  • Java:在基元上同步?

    在我们的系统中 我们有一个方法 当使用特定 ID 调用它时 它会执行一些工作 public void doWork long id 现在 这项工作可以针对不同的 ID 并发完成 但如果 2 个线程使用相同的 ID 调用该方法 则一个线程应该
  • Elasticsearch 丢弃了太多请求——缓冲区会改善情况吗?

    我们有一个工作集群 将索引请求发送到 4 节点 Elasticsearch 集群 文档在生成时就会被索引 并且由于工作人员具有高度并发性 Elasticsearch 在处理所有请求时遇到了困难 给出一些数字 工作人员同时处理多达 3 200
  • 我不明白侦听器中 lambda 表达式的参数传递

    我开始学习 Kotlin 没多久 关于 Android 侦听器中 lambda 表达式的传递 有些部分我不明白 In JAVA botton setOnClickListener new View OnClickListener Overr
  • 如何获取和使用 Alexa 技能意图响应的确认“是”或“否”

    我正在开发一项 Alexa 技能 在启动时它会询问Do you want to perform something 取决于用户的回复 yes or no 我想发起另一个意图 var handlers LaunchRequest functi
  • 在 Android Studio 中将文件(使用 Git 跟踪)从 Java 转换为 Kotlin

    Android Studio 2 3 2 中从 Java 到 Kotlin 的转换 3 0 中的行为相同 会创建一个新文件并删除以前的文件 所以 Git 对这个转换一无所知 并且 git 历史记录不会保存 在 Intellij Idea 中
  • 如何将 LockBox 3 安装到 Delphi 7 中?

    这是我第一次安装 Lockbox 的库 我从sourceforge下载了3 4 3版本 并拥有Delphi 7 第一步是让这个傻瓜在Delphi 7下编译 这真是太糟糕了 我确实希望这些组件在安装后更易于使用 好的 我有一个看起来像这样的单
  • 实现 Parcelable 接口时如何读/写布尔值?

    我正在尝试做一个ArrayList Parcelable为了将自定义对象列表传递给活动 我开始写一个myObjectList扩展的类ArrayList
  • 如何安装旧的SDK平台

    我想针对 Android 1 3 平台而不是最新的 2 2 进行测试 Here is how my Android SDK and AVD Manager look likes However I was expecting screen
  • 当存储日期 <= 最近 24 小时时,Django 返回计数

    我是菜鸟 所以这可能是一个简单的问题 但它让我难住了 我正在创建一个测试表单 以便每次用户创建文档时 创建文档的日期和时间都将存储在 CreatedDocumentDetails 模型中 我还没有实现这个代码 我专注于返回过去 24 小时内
  • 如何在控制器中合并 Laravel 对象

    我有一个控制器 我想将多个表中的数据与并行结构结合起来 我最终想要得到的是一个可以从控制器返回的对象 这样我就可以在 Backbone 中解析它 我想做这样的事情 public function index mc MainContact w
  • 为什么左值在某些地方转换为值而不是其他地方? [复制]

    这个问题在这里已经有答案了 考虑这段代码 int x 99 int p x p p 1 为什么要这样做 p在左侧和右侧 运营商不同 编译器如何知道使用左 p成为对象x和右边的 p成为x 具体来说 如果编译器评估 p成为x 为什么 p左侧的计
  • 如何在VBA中安排邮件发送到特定时间

    如何在VBA中安排邮件发送到特定时间 生成邮件的代码 Set olApp CreateObject Outlook application Set olItem olApp CreateItem 0 olItem display olIte
  • Django:按下按钮时提供动态生成的数据作为附件

    问题概述 我正在创建一个基于 Django 的客户端 旨在从 Web 服务返回数据 该项目的目标是根据用户在表单中选择的值从 Web 服务将数据返回给用户 表单提交后 会生成一个查询字符串 发送到 Web 服务 并以字符串形式返回页面数据
  • 在 R 上时 vi 模式到 emacs 模式

    有时 在 R 控制台上 我不小心输入了未知的键盘快捷键 该快捷键将编辑模式从 emacs 更改为 vi 有谁知道从一个键更改为另一个键的组合键通常是什么 我在 Fedora 16 机器上 我查了这方面的信息question https st
  • NSTextView 颜色和字体清除后重置

    我为 NSPanel 内的 NSTextView 设置了一些默认字体和颜色 但是 当我用以下命令清除视图时setString 不仅文本消失 所有默认颜色 字体格式也消失 当我做了另一个之后setString 文本变为默认字体并再次变黑 有人
  • Rust/rocket 将变量传递到端点

    不符合我的喜好 但我今天被迫编写一些 Rust 所以我尝试创建一个只有一个端点的 Rocket 实例 但是 在该端点上我需要访问在 main 期间创建的变量 该变量需要很长时间才能实例化 所以这就是我在那里这样做的原因 我的问题是我找不到安
  • 使用 SwiftUI 成功登录后导航

    我正在使用 Firebase 和 SwiftUI 以用户身份登录 我一切正常 但无法弄清楚用户成功登录后如何导航到下一页 导航链接对我来说似乎很奇怪 所以我想知道是否有其他方法可以导航到下一个视图 这LoginView包含登录屏幕和Logi