2015-03-02 79 views
6

我在處理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

回答

5

我用一個「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

0

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

運行您的項目。

1

這裏是我做的,它工作正常:

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 
}