Establecer programáticamente el controlador de vista inicial utilizando Storyboards

¿Cómo configuro programáticamente InitialViewController para un Storyboard? Quiero abrir mi storyboard a una vista diferente dependiendo de alguna condición que puede variar desde el inicio hasta el lanzamiento.

Cómo sin un controlador de vista inicial ficticio

Asegúrese de que todos los controladores de vista iniciales tengan una identificación Storyboard.

En el guión gráfico, desmarque el atributo “Is initial View Controller” del primer controlador de vista.

Si ejecuta su aplicación en este punto, leerá:

 Failed to instantiate the default view controller for UIMainStoryboardFile 'MainStoryboard' - perhaps the designated entry point is not set? 

Y notará que la propiedad de su ventana en el delegado de la aplicación ahora es nula.

En la configuración de la aplicación, vaya a su destino y a la pestaña Info . Allí, borre el valor del Main storyboard file base name . En la pestaña General , borre el valor de Main Interface . Esto eliminará la advertencia.

Cree la ventana y el controlador de vista inicial deseado en la aplicación del delegado de la application:didFinishLaunchingWithOptions: method:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]; UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; UIViewController *viewController = // determine the initial view controller here and instantiate it with [storyboard instantiateViewControllerWithIdentifier:]; self.window.rootViewController = viewController; [self.window makeKeyAndVisible]; return YES; } 

Para todos los amantes de Swift , esta es la respuesta de @Travis traducida a SWIFT :

Haga lo que @Travis explicó antes del código de Objective C. Entonces,

 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 sería el nuevo controlador de vista inicial que le gustaría mostrar.

Los pasos explicados:

  1. Cree una nueva ventana con el tamaño de la ventana actual y configúrela como nuestra ventana principal
  2. Crea una instancia de un guión gráfico que podamos usar para crear nuestro nuevo controlador de vista inicial
  3. Crea una instancia de nuestro nuevo controlador de vista inicial basado en su ID Storyboard
  4. Configura el controlador de vista raíz de nuestra nueva ventana como nuestro nuevo controlador que acabamos de iniciar
  5. Hacer visible nuestra nueva ventana

¡Disfruta y feliz progtwigción!

Puede establecer programáticamente el controlador raíz de la ventana clave en la aplicación (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions

por ejemplo:

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

Swift 3: actualización del código de @ victor-sigler

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { self.window = UIWindow(frame: UIScreen.main.bounds) // Assuming your storyboard is named "Main" let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) // Add code here (eg if/else) to determine which view controller class (chooseViewControllerA or chooseViewControllerB) and storyboard ID (chooseStoryboardA or chooseStoryboardB) to send the user to if(condition){ let initialViewController: chooseViewControllerA = mainStoryboard.instantiateViewController(withIdentifier: "chooseStoryboardA") as! chooseViewControllerA self.window?.rootViewController = initialViewController ) }else{ let initialViewController: chooseViewControllerB = mainStoryboard.instantiateViewController(withIdentifier: "chooseStoryboardB") as! chooseViewControllerB self.window?.rootViewController = initialViewController ) self.window?.makeKeyAndVisible( return true } 

Puede configurar Navigationviewcontroller como un controlador de vista principal. Esta idea puede usarse para el inicio de sesión automático según los requisitos de la aplicación.

 UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil]; UIViewController viewController = (HomeController*)[mainStoryboard instantiateViewControllerWithIdentifier: @"HomeController"]; UINavigationController navController = [[UINavigationController alloc] initWithRootViewController:viewController]; self.window.rootViewController = navController; if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { // do stuff for iOS 7 and newer navController.navigationBar.barTintColor = [UIColor colorWithRed:88/255.0 green:164/255.0 blue:73/255.0 alpha:1.0]; navController.navigationItem.leftBarButtonItem.tintColor = [UIColor colorWithRed:88/255.0 green:164/255.0 blue:73/255.0 alpha:1.0]; navController.navigationBar.tintColor = [UIColor whiteColor]; navController.navigationItem.titleView.tintColor = [UIColor whiteColor]; NSDictionary *titleAttributes =@{ NSFontAttributeName :[UIFont fontWithName:@"Helvetica-Bold" size:14.0], NSForegroundColorAttributeName : [UIColor whiteColor] }; navController.navigationBar.titleTextAttributes = titleAttributes; [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; } else { // do stuff for older versions than iOS 7 navController.navigationBar.tintColor = [UIColor colorWithRed:88/255.0 green:164/255.0 blue:73/255.0 alpha:1.0]; navController.navigationItem.titleView.tintColor = [UIColor whiteColor]; } [self.window makeKeyAndVisible]; 

Para usuarios de StoryboardSegue

 UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil]; // Go to Login Screen of story board with Identifier name : LoginViewController_Identifier LoginViewController *loginViewController = (LoginViewController*)[mainStoryboard instantiateViewControllerWithIdentifier:@“LoginViewController_Identifier”]; navigationController = [[UINavigationController alloc] initWithRootViewController:testViewController]; self.window.rootViewController = navigationController; [self.window makeKeyAndVisible]; // Go To Main screen if you are already Logged In Just check your saving credential here if([SavedpreferenceForLogin] > 0){ [loginViewController performSegueWithIdentifier:@"mainview_action" sender:nil]; } 

Gracias

Abra la tabla principal, seleccione la vista que desee comenzar primero, luego abra Utilidades -> Atributos. Debajo del “Controlador de vista” verá el botón de opción “Es el controlador de vista inicial”. Solo selecciónelo.

— A la pregunta revisada:

Puede ser que pueda intentar esto: escriba un método en la sección ViewDidLoad de su vista inicial y cuando el método se ejecute al iniciarse la aplicación, el método desencadena un cambio a otra vista.

No creo que sea posible. En su lugar, puede tener un controlador inicial que tendrá segues para diferentes controladores de vista. Al inicio, puede decidir qué segue realizar de forma programática.

Puede configurar initial view controller utilizando el Constructor de interfaz, así como programáticamente.

Debajo está el acercamiento usado para programáticamente.

C objective :

  self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]; UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"HomeViewController"]; //  self.window.rootViewController = viewController; [self.window makeKeyAndVisible]; return YES; 

Swift:

  self.window = UIWindow(frame: UIScreen.mainScreen().bounds) let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) var objMainViewController: MainViewController = mainStoryboard.instantiateViewControllerWithIdentifier("MainController") as! MainViewController self.window?.rootViewController = objMainViewController self.window?.makeKeyAndVisible() return true 

Creé una clase de enrutamiento para manejar la navegación dinámica y mantener la clase AppDelegate limpia, espero que ayude a otros también.

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

Y en tu AppDelegate llama esto

  self.window = UIWindow(frame: UIScreen.main.bounds) Routing.decideInitialViewController(window: self.window!) 

Otra solución con el uso de Swift 3 y Swift 4 con evitar la fuerza de lanzamiento es como esto

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { self.window = UIWindow(frame: UIScreen.main.bounds) let storyboard = UIStoryboard(name: "Main", bundle: nil) guard let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewController") as? YourViewController else { return false } self.window?.rootViewController = viewController self.window?.makeKeyAndVisible() return true } 

Y a continuación está usando con UINavigationController

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { self.window = UIWindow(frame: UIScreen.main.bounds) let storyboard = UIStoryboard(name: "Main", bundle: nil) guard let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewController") as? YourViewController else { return false } let navigationController = UINavigationController(rootViewController: viewController) self.window?.rootViewController = navigationController self.window?.makeKeyAndVisible() return true } 

En AppDelegate.swift puedes agregar el siguiente código:

 let sb = UIStoryboard(name: "Main", bundle: nil) let vc = sb.instantiateViewController(withIdentifier: "YourViewController_StorboardID") self.window?.rootViewController = vc self.window?.makeKeyAndVisible() 

Por supuesto, debe implementar su lógica, en función de qué criterio elegirá un controlador de vista apropiado.

Además, no olvide agregar una identidad (seleccionar guión gráfico -> Escena del controlador -> Mostrar el inspector de identidad -> asignar StorboardID).

Hace unos días me encontré en la misma situación. Un truco muy simple resolvió este problema. Configuré mi controlador de vista inicial antes de launch2. Si el controlador de vista inicial es el controlador correcto, está configurado como visible en viewDidLoad. De lo contrario, se realiza una transición al controlador de vista deseado. Funciona perfectamente en iOS 6.1 y superior. Estoy seguro de que funciona en versiones anteriores de iOS.

Gracias modificó esto de la siguiente manera en AppDelegate:

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { //Some code to check value of pins if pins! == "Verified"{ print(pins) self.window = UIWindow(frame: UIScreen.mainScreen().bounds) let mainStoryboard: UIStoryboard = UIStoryboard(name: "HomePage", bundle: nil) let exampleViewController: UINavigationController = mainStoryboard.instantiateViewControllerWithIdentifier("SBHP") as! UINavigationController self.window?.rootViewController = exampleViewController self.window?.makeKeyAndVisible() }else{ print(pins) self.window = UIWindow(frame: UIScreen.mainScreen().bounds) let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) let exampleViewController: UINavigationController = mainStoryboard.instantiateViewControllerWithIdentifier("SBUser") as! UINavigationController self.window?.rootViewController = exampleViewController self.window?.makeKeyAndVisible() } 

Solución simple encontrada: no es necesario eliminar la “verificación del controlador de vista inicial” del guión gráfico y editar la pestaña Información del proyecto y usar makeKeyAndVisible , solo colocar

 self.window.rootViewController = rootVC; 

en

 - (BOOL) application:didFinishLaunchingWithOptions: 
 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 

Otra forma es presentar viewController,

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

Primero necesitas crear un objeto de tu guión gráfico y luego cambiar de raíz (si es necesario) y luego tomar una referencia del controlador de vista particular que se empuja al controlador de vista actual (si cambias de raíz) de lo contrario solo está presente el controlador de vista nuevo que puedes

Swift 4, Xcode 9

en el archivo AppDelegate.swift

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { let storyboard = UIStoryboard(name: "Main", bundle: nil) let firstVC = storyboard.instantiateViewController(withIdentifier: "firstViewController") as! firstViewController self.window?.rootViewController = firstVC } 
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { self.window = UIWindow(frame: UIScreen.main.bounds) let storyboard = UIStoryboard(name: "Main", bundle: nil) if (PreferenceHelper.getAccessToken() != "") { let initialViewController = storyboard.instantiateViewController(withIdentifier: "your View Controller Identifier") self.window?.rootViewController = initialViewController } else { let initialViewController = storyboard.instantiateViewController(withIdentifier: "your View Controller identifier") self.window?.rootViewController = initialViewController } self.window?.makeKeyAndVisible() return true } /* use your view Controller identifier must use it doubles quotes**strong text** 

Seleccione el controlador de vista que desea abrir primero y vaya al inspector de atributos. Ir a la escena inicial y verificar es la opción del controlador de vista inicial.

Este será su controlador de vista inicial que se abrirá primero cuando se inicie la aplicación.