xcode 带有 Swift 和 iOS 8 Storyboard 的登录屏幕

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28817519/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 06:45:19  来源:igfitidea点击:

Login Screen with Swift and iOS 8 Storyboard

iosxcodeswift

提问by user3684980

I have having a lot of trouble handling the login flow of my iOS app. An image of the storyboard I am trying to achieve is below

我在处理 iOS 应用程序的登录流程时遇到了很多麻烦。我试图实现的故事板的图像如下

enter image description here

在此处输入图片说明

I am trying to achieve an optional login screen which is presented only when a user first opens the app and has not logged in. Currently, I have the Tab Bar Controller set as the root view controller. I can not figure out how to handle swapping between these view controllers, however.

我正在尝试实现一个可选的登录屏幕,该屏幕仅在用户首次打开应用程序且尚未登录时显示。目前,我将 Tab Bar Controller 设置为根视图控制器。但是,我不知道如何处理这些视图控制器之间的交换。

I have tried to simply push the login screen with the following code. However, it does not work. I believe the problem that a tab bar controller is not allowed to push new view controllers.

我尝试使用以下代码简单地推送登录屏幕。但是,它不起作用。我相信标签栏控制器不允许推送新视图控制器的问题。

    func application(application: UIApplication, didFinishLaunchingWithOptions  launchOptions: [NSObject: AnyObject]?) -> Bool {
    //stuff

    if userLoggedIn {
        // Do nothing
    } else {
        //get access to login view
        var storyboard = UIStoryboard(name: "Main", bundle: nil)
        var viewController =    storyboard.instantiateViewControllerWithIdentifier("signupView") as UIViewController;

        // Then push login view
        var rootViewController = self.window!.rootViewController as UITabBarController;
        rootViewController.pushViewController(viewController, animated: true)
    }

    // Override point for customization after application launch.
    return true
}

Is there a way to switch view controllers without pushing within a navigation controller? Any advice on how to handle this sort of login flow would be greatly appreciated.

有没有办法在不推入导航控制器的情况下切换视图控制器?任何有关如何处理此类登录流程的建议将不胜感激。

回答by Chris Wagner

I achieve this with a "LaunchViewController" that determines if it should present the Login view or the main navigation controller.

我使用“LaunchViewController”来实现这一点,它决定了它是否应该显示登录视图或主导航控制器。

Mark the launch view your initial view in the storyboard and write the logic in there to determine which to present. This process is often very quick and unnoticeable to the user.

在故事板中将启动视图标记为您的初始视图,并在其中编写逻辑以确定要呈现的视图。这个过程通常非常快速并且用户不会注意到。

UPDATE:

更新

As mentioned in my comment I've gone a different direction. Now in the App Delegate's application(application:didFinishLaunchingWithOptions:)method I perform the logic necessary to determine which view should be the rootViewControllerand set it there using the following.

正如我在评论中提到的,我走了不同的方向。现在在 App Delegate 的application(application:didFinishLaunchingWithOptions:)方法中,我执行必要的逻辑来确定哪个视图应该是 ,rootViewController并使用以下内容将其设置在那里。

extension AppDelegate {

    enum LaunchViewController {
        case Login, Dashboard

        var viewController: UIViewController {
            switch self {
            case .Login: return StoryboardScene.Login.LoginScene.viewController()
            case .Dashboard: return StoryboardScene.Dashboard.initialViewController()
            }
        }

        /// Sets `UIWindow().rootViewController` to the appropriate view controller, by default this runs without an animation.
        func setAsRootviewController(animated animated: Bool = false) {
            let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
            let window = appDelegate.window!
            let launchViewController = viewController

            log.info?.message("Setting \(launchViewController.dynamicType) as rootViewController")
            if let rootViewController = window.rootViewController where rootViewController.dynamicType != launchViewController.dynamicType && animated {
                let overlayView = UIScreen.mainScreen().snapshotViewAfterScreenUpdates(false)
                launchViewController.view.addSubview(overlayView)

                UIView.animateWithDuration(0.3, animations: {
                    overlayView.alpha = 0.0
                    },
                    completion: { _ in
                        overlayView.removeFromSuperview()
                });
            }

            window.rootViewController = launchViewController
            window.restorationIdentifier = String(launchViewController.dynamicType)

            if window.keyWindow == false {
                window.makeKeyAndVisible()
            }
        }
    }
}

Note that StoryboardSceneis not a default type, I am using https://github.com/AliSoftware/SwiftGento generate that.

请注意,这StoryboardScene不是默认类型,我使用https://github.com/AliSoftware/SwiftGen来生成它。

My App Delegate method looks something like this.

我的 App Delegate 方法看起来像这样。

if window == nil {
    window = UIWindow(frame: UIScreen.mainScreen().bounds)
}

if isRestoringState == false {
    if let _ = lastUsedAccount {
        LaunchViewController.Dashboard.setAsRootviewController()
    } else {
        LaunchViewController.Login.setAsRootviewController()
    }
}

UPDATE with Logout method for Comment

使用注销方法更新评论

func handleLogout(notification: NSNotification) {
  LaunchViewController.Login.setAsRootviewController(animated: true)
  lastUsedAccount = nil
}

回答by karl j

Here is what i did and it works fine :

这是我所做的并且工作正常:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    if (!AppData.sharedInstance.loggedIn) {
        let signInNavigation = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("SignInNavigationControllerIdentifier") as? UINavigationController
        self.window!.rootViewController = signInNavigation;
    }
    return true
}

回答by Mohammad Nurdin

Set Is Initial View Controllerfor LoginViewController.

Is Initial View Controller为 LoginViewController设置。

enter image description here

在此处输入图片说明

Remove from AppDelegate.swiftand place it in LoginViewController.

从 中取出AppDelegate.swift并放入LoginViewController.

if userLoggedIn {
        // Do nothing
    } else {
        //get access to login view
        var storyboard = UIStoryboard(name: "Main", bundle: nil)
        var viewController =    storyboard.instantiateViewControllerWithIdentifier("signupView") as UIViewController;

        // Then push login view
        var rootViewController = self.window!.rootViewController as UITabBarController;
        rootViewController.pushViewController(viewController, animated: true)
    }

Run your project.

运行你的项目。