Login screen with Swift and iOS 8 storyboards

I have a lot of problems with the login processing of my iOS application. The image of the storyboard I am trying to achieve is below

enter image description here

I try to get an additional login screen, which is presented only when the user first opens the application and has not logged in. Currently, I have a tab bar controller installed as the root view controller. However, I cannot figure out how to handle the data exchange between these view controllers.

I tried just clicking the login screen with the following code. However, this does not work. I believe the problem is that the tab bar controller is not allowed to introduce 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 clicking on the navigation controller? Any advice on how to handle this type of login would be greatly appreciated.

+6
source share
3 answers

I achieve this with the “LaunchViewController”, which determines whether it should represent the “Input” view or the main navigation controller.

Mark the initial run in the storyboard and write the logic there to determine what to represent. This process is often very fast and invisible to the user.

UPDATE

As mentioned in my comment, I went in a different direction. Now in the App Delegate application(application:didFinishLaunchingWithOptions:) I follow the logic needed to determine what kind of rootViewController should be and set it there using the following.

 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() } } } } 

Please note that StoryboardScene not the default type; I use https://github.com/AliSoftware/SwiftGen to create it.

My application delegation method looks something like this.

 if window == nil { window = UIWindow(frame: UIScreen.mainScreen().bounds) } if isRestoringState == false { if let _ = lastUsedAccount { LaunchViewController.Dashboard.setAsRootviewController() } else { LaunchViewController.Login.setAsRootviewController() } } 

UPDATE with exit method for comments

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

Here is what I did and it works great:

 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 } 
+1
source

Set Is Initial View Controller for LoginViewController.

enter image description here

Remove from AppDelegate.swift and put it in 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 the project.

0
source

Source: https://habr.com/ru/post/983231/


All Articles