我如何以编程方式设置一个故事板的InitialViewController ?我想打开我的故事板到一个不同的视图这取决于不同的启动条件。


当前回答

对于所有喜欢霉霉的人,下面是@Travis用Swift翻译的答案:

做@Travis在Objective C代码之前解释的事情。然后,

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

    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
    let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    var exampleViewController: ExampleViewController = mainStoryboard.instantiateViewControllerWithIdentifier("ExampleController") as! ExampleViewController

    self.window?.rootViewController = exampleViewController

    self.window?.makeKeyAndVisible()

    return true
}

ExampleViewController将是您想要显示的新的初始视图控制器。

步骤解释如下:

创建一个与当前窗口大小相同的新窗口,并将其设置为主窗口 实例化一个故事板,我们可以用它来创建新的初始视图控制器 基于Storyboard ID实例化我们新的初始视图控制器 将新窗口的根视图控制器设置为我们刚刚启动的新控制器 使新窗口可见

享受和快乐的编程!

其他回答

几天前我也遇到了同样的情况。一个非常简单的技巧解决了这个问题。 我设置在launch2之前隐藏我的初始视图控制器。如果初始视图控制器是正确的控制器,它在viewDidLoad中被设置为可见。否则,执行一个segue到所需的视图控制器。它在iOS 6.1及以上版本运行良好。我确信它适用于早期版本的iOS。

如果你不想改变applicationDidFinish,你可以做下面的技巧:

设置导航控制器为初始视图控制器,并分配给它一个自定义类'MyNavigationController'。然后你可以在viewDidLoad期间调整它的根视图控制器——它会覆盖你在故事板中设置的根视图控制器。

class MyNavigationController: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
        if !isLoggedIn() {
            viewControllers = [R.storyboard.authentication.loginView()!]
        }
    }

    private func isLoggedIn() -> Bool {
        return false
    }

}

(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions你可以通过编程方式设置(BOOL)应用程序中的关键窗口的rootViewController

例如:

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if (shouldShowAnotherViewControllerAsRoot) {
        UIStoryboard *storyboard = self.window.rootViewController.storyboard;
        UIViewController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:@"rootNavigationController"];
        self.window.rootViewController = rootViewController;
        [self.window makeKeyAndVisible];
    }

    return YES;
}

我创建了一个路由类来处理动态导航和保持干净的AppDelegate类,我希望它也能帮助其他。

//
//  Routing.swift
// 
//
//  Created by Varun Naharia on 02/02/17.
//  Copyright © 2017 TechNaharia. All rights reserved.
//

import Foundation
import UIKit
import CoreLocation

class Routing {

    class func decideInitialViewController(window:UIWindow){
        let userDefaults = UserDefaults.standard
        if((Routing.getUserDefault("isFirstRun")) == nil)
        {
            Routing.setAnimatedAsInitialViewContoller(window: window)
        }
        else if((userDefaults.object(forKey: "User")) != nil)
        {
            Routing.setHomeAsInitialViewContoller(window: window)
        }
        else
        {
            Routing.setLoginAsInitialViewContoller(window: window)
        }

    }

    class func setAnimatedAsInitialViewContoller(window:UIWindow) {
        Routing.setUserDefault("Yes", KeyToSave: "isFirstRun")
        let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let animatedViewController: AnimatedViewController = mainStoryboard.instantiateViewController(withIdentifier: "AnimatedViewController") as! AnimatedViewController

        window.rootViewController = animatedViewController
        window.makeKeyAndVisible()
    }

    class func setHomeAsInitialViewContoller(window:UIWindow) {
        let userDefaults = UserDefaults.standard
        let decoded  = userDefaults.object(forKey: "User") as! Data
        User.currentUser = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! User

        if(User.currentUser.userId != nil && User.currentUser.userId != "")
        {
            let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            let homeViewController: HomeViewController = mainStoryboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
            let loginViewController: UINavigationController = mainStoryboard.instantiateViewController(withIdentifier: "LoginNavigationViewController") as! UINavigationController
            loginViewController.viewControllers.append(homeViewController)
            window.rootViewController = loginViewController
        }
        window.makeKeyAndVisible()
    }

    class func setLoginAsInitialViewContoller(window:UIWindow) {
        let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let loginViewController: UINavigationController = mainStoryboard.instantiateViewController(withIdentifier: "LoginNavigationViewController") as! UINavigationController

        window.rootViewController = loginViewController
        window.makeKeyAndVisible()
    }

  class func setUserDefault(_ ObjectToSave : Any?  , KeyToSave : String)
    {
        let defaults = UserDefaults.standard

        if (ObjectToSave != nil)
        {

            defaults.set(ObjectToSave, forKey: KeyToSave)
        }

        UserDefaults.standard.synchronize()
    }

    class func getUserDefault(_ KeyToReturnValye : String) -> Any?
    {
        let defaults = UserDefaults.standard

        if let name = defaults.value(forKey: KeyToReturnValye)
        {
            return name as Any
        }
        return nil
    }

    class func removetUserDefault(_ KeyToRemove : String)
    {
        let defaults = UserDefaults.standard
        defaults.removeObject(forKey: KeyToRemove)
        UserDefaults.standard.synchronize()
    }

}

在AppDelegate中调用这个

 self.window = UIWindow(frame: UIScreen.main.bounds)
 Routing.decideInitialViewController(window: self.window!)
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = mainStoryboard.instantiateViewController(withIdentifier: "storyBoardid") as! ViewController
let navigationController = UINavigationController(rootViewController: vc)
UIApplication.shared.delegate.window?.rootViewController = navigationController

另一种方法是present viewController,

let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = mainStoryboard.instantiateViewController(withIdentifier: "storyBoardid") as! ViewController
self.present(vc,animated:true,completion:nil)

首先你需要创建storyboard的对象然后改变根(如果需要)然后你引用特定的视图控制器它会被推送当前视图控制器(如果你改变根)否则它会呈现新的视图控制器