简体   繁体   English

如何在 swiftUI 中登录后显示视图

[英]How to show view after login view in swiftUI

In my application I start with a LoginView which makes an API call to the backend for authentication.在我的应用程序中,我从 LoginView 开始,它对后端进行 API 调用以进行身份验证。 In case this is successfull (in a completion handler, i want to show the FeedView(). With UIKit this is all pretty simple trying to figure out how to do this with SwiftUI. So How can I show a new View programmatically (I don't have a NavigationView)?如果这是成功的(在完成处理程序中,我想显示 FeedView()。使用 UIKit 这一切都非常简单,试图弄清楚如何使用 SwiftUI 做到这一点。那么我如何以编程方式显示新视图(我不'没有导航视图)?

You can have a conditional view like so:您可以有这样的条件视图:

struct MakeSureUserIsLoggedInView: View {
  @State private var loggedIn = false
  var body: some View {
    if loggedIn {
      FeedView()
    } else {
      LoginView { // your login view with completion handler
        loggedIn = true
      }
    }
  }
}

Notice how we use @State to switch between what view is shown.注意我们如何使用@State在显示的视图之间切换。

If you don't want to use a NavigationView , you have several options:如果您不想使用NavigationView ,您有几个选择:

  1. A SwiftUI-native style would be simply to have a parent view which holds your view, and other views. SwiftUI 原生样式只是拥有一个包含您的视图和其他视图的父视图。 You can have a property on a shared ViewModel and the parent view can return a different child view depending on the value of the view model您可以在共享ViewModel上拥有一个属性,并且父视图可以根据视图 model 的值返回不同的子视图

  2. Displaying a new view modally (this is easiest)以模态方式显示新视图(这是最简单的)

  3. Using UIKit navigation - this is my preferred method in complex apps where you can simply navigate around the app using UIViewControllers, with a SwiftUI view pinned to the edges使用 UIKit 导航 - 这是我在复杂应用程序中的首选方法,您可以使用 UIViewControllers 简单地在应用程序中导航,并将 SwiftUI 视图固定到边缘

I can go into more detail on any of these, with some sample code from my own projects, if you would like.如果您愿意,我可以 go 更详细地了解其中任何一个,以及我自己项目中的一些示例代码。 Option 1 is probably the most natural for SwiftUI and you can even animate the transitions pretty nicely with things like matchedGeometryView if you use this option.对于 SwiftUI 来说,选项 1 可能是最自然的,如果您使用此选项,您甚至可以使用matchedGeometryView之类的东西很好地为过渡设置动画。

You could use EnvironmentObject to control your user Session, the example below is with Firebase Authentication.您可以使用 EnvironmentObject 来控制您的用户 Session,以下示例使用 Firebase 身份验证。 Take care you need to add an environmentObject in your parent view.注意你需要在你的父视图中添加一个 environmentObject 。

Main:主要的:

import SwiftUI
import Firebase

@main
struct YourApp: App {

@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

var body: some Scene {
    WindowGroup {
        ContentView().environmentObject(SessionManager.shared)
    }
}

//Firebase init
class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication,   didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        FirebaseApp.configure()
        return true
      }
}
}

ContentView: access your environment var ContentView:访问您的环境变量

struct ContentView: View {

@EnvironmentObject var session: SessionManager

var body: some View {
    
    Group {
        if session.loggedUser != nil {
            FeedView()
        }
        else {
            LoginView()
        }
}
}

Sample Session Manager (Firebase sample, if you have another backend you need to add your logic).示例 Session 管理器(Firebase 示例,如果您有另一个后端,则需要添加逻辑)。 Then is possible to call logout wherever you want in your app, this action change ContentView State and display LoginView:然后可以在应用程序中的任何位置调用注销,此操作更改 ContentView State 并显示 LoginView:

import Foundation
import SwiftUI
import Firebase

class SessionManager: NSObject, ObservableObject {
    
    @Published var loggedUser: User?
    static let shared = SessionManager()
    private let auth = Auth.auth()
    
    var handle : AuthStateDidChangeListenerHandle?
    
    override private init() {
        loggedUser = auth.currentUser
        super.init()
        handle = auth.addStateDidChangeListener(authStateChanged)
    }
    
    private func authStateChanged(with auth: Auth, user: User?) {
        guard user != self.loggedUser else { return }
        self.loggedUser = user
    }
        
    func logout() {
        do {
            try Auth.auth().signOut()
        } catch(let error) {
            debugPrint(error.localizedDescription)
        }
    }
    
    func unbind() {
        if let handle = handle {
            Auth.auth().removeStateDidChangeListener(handle)
        }
    }
    
    deinit {
        unbind()
    }
    
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM