使用Swift和iOS登录屏幕8 Storyboard

问题描述:

我在处理iOS应用程序的登录流程时遇到了很多麻烦。故事板,我想实现的图像低于使用Swift和iOS登录屏幕8 Storyboard

enter image description here

我想实现它提出只有当用户第一次打开应用程序,并在没有登录可选登录屏幕。目前,我将选项卡栏控制器设置为根视图控制器。但我无法弄清楚如何处理这些视图控制器之间的交换。

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

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 
} 

有没有方法可以切换视图控制器,而无需在导航控制器内推动?任何有关如何处理这种登录流的建议将不胜感激。

+0

这是你的整个didFinishLaunchingWithOptions方法的代码?如果用户登录,你如何转换到第一个控制器?我猜这是自动与故事板完成的...在这种情况下,您正尝试在代码中的错误位置推送此登录视图... – 2015-03-02 20:07:55

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

将启动标记为在故事板中查看您的初始视图,并在其中写入逻辑以确定要呈现的内容。这个过程对用户来说通常非常快并且不明显。

UPDATE

正如我在评论中提及了,我走了不同的方向。现在在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() 
      } 
     } 
    } 
} 

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

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

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

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

更新与退出方法评论

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

您是否编写逻辑来确定要在viewDidLoad()或其他位置呈现哪个? – Kaunteya 2016-04-04 07:23:59

+0

我已经在一个新的应用程序中走了另一个方向,我正在努力,我更喜欢。在'application(application:didFinishLaunchingWithOptions:)'中的App Delegate中,我确定应该呈现哪个视图,并将相应的视图设置为'rootViewController'。用一些示例代码更新了我的答案。 – 2016-04-04 17:26:49

+0

@ChrisWagner你如何处理用户注销?你只是把'window'的'rootViewController'改回''.Login'视图控制器?如果是这样,你在转换过程中会遇到动画不佳的情况吗?在启动注销后,转换回身份验证视图控制器时,我似乎会看到奇怪的动画。 – 2016-10-19 01:25:45

为LoginViewController设置Is Initial View Controller

enter image description here

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

运行您的项目。

这里是我做的,它工作正常:

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 
}