¿Cómo configuro programáticamente el InitialViewController
Storyboard? Quiero abrir mi guión gráfico a una vista diferente dependiendo de alguna condición que puede variar de un lanzamiento a otro.
¿Cómo configuro programáticamente el InitialViewController
Storyboard? Quiero abrir mi guión gráfico a una vista diferente dependiendo de alguna condición que puede variar de un lanzamiento a otro.
Respuestas:
Cómo prescindir de un controlador de vista inicial ficticio
Asegúrese de que todos los controladores de vista iniciales tengan una ID de Storyboard.
En el guión gráfico, desmarque el atributo "Es el controlador de vista inicial" 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 su propiedad de ventana en el delegado de la aplicación ahora es nula.
En la configuración de la aplicación, vaya a su objetivo y a la Info
pestaña. Hay claro el valor de Main storyboard file base name
. En la General
pestaña, borre el valor de Main Interface
. Esto eliminará la advertencia.
Cree la ventana y el controlador de vista inicial deseado en el application:didFinishLaunchingWithOptions:
método del delegado de la aplicación :
- (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:<storyboard id>];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
return YES;
}
didFinishLaunchingWithOptions
Se llama a @bdv cuando la aplicación se inicia en un nuevo proceso. Si va a la pantalla de inicio y vuelve a la aplicación, este método no se volverá a invocar. (A menos que iOS finalice debido a restricciones de memoria). Intente detener la aplicación e iniciarla nuevamente desde su IDE. Si el problema continúa, publícalo en SO y estaré encantado de ayudarte, amigo.
self.window = UIWindow(frame: UIScreen.mainScreen().bounds) var storyboard = UIStoryboard(name: "Main", bundle: nil) var viewController: UIViewController = // self.window!.rootViewController = viewController self.window!.makeKeyAndVisible()
Para todos los amantes de Swift , aquí está la respuesta de @Travis traducida a SWIFT :
Haz lo que @Travis explicó antes del código del objetivo C. Luego,
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
}
El ExampleViewController
sería el nuevo controlador de vista inicial que le gustaría mostrar.
Los pasos explicados:
¡Disfruta y feliz programación!
Puede configurar mediante programación el rootViewController de la ventana clave en (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;
}
init()
/ deinit()
, pero sin ejecutar viewDidLoad()
o inicializar correctamente IBOutlet
-s. Asegúrese de que el código esté listo para ello.
Swift 3: Actualización al 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 (e.g. 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 el controlador rootviewcontroller de navegación 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 mainstoryboard, seleccione la vista que desea que comience 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ónalo.
--- A la pregunta revisada:
Puede intentarlo: escriba un método en la sección ViewDidLoad de su vista inicial y cuando el método se ejecute al iniciar la aplicación, el método desencadena un segue a otra vista.
SWIFT 5
Si no tiene un ViewController establecido como ViewController inicial en el guión gráfico, debe hacer 2 cosas:
Finalmente, ahora puede agregar su código en SceneDelegate:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
// Make sure you set an Storyboard ID for the view controller you want to instantiate
window?.rootViewController = storyboard.instantiateViewController(withIdentifier: identifier)
window?.makeKeyAndVisible()
}
Failed to instantiate the default view controller for UIMainStoryboardFile 'Main' - perhaps the designated entry point is not set
advertencia que tenía después de que decidí instanciar mi VC inicial en el código. Un punto importante, cuando @ rs7 dice "eliminar el campo de nombre del guión gráfico", significan toda la fila de la lista, no solo el contenido del campo en sí.
Puede configurar initial view controller
usando Interface Builder, así como mediante programación.
A continuación se muestra el enfoque utilizado programáticamente.
C objetivo :
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"HomeViewController"]; // <storyboard id>
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
return YES;
Rápido:
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 limpia la clase AppDelegate, espero que también ayude a otros.
//
// 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 a esto
self.window = UIWindow(frame: UIScreen.main.bounds)
Routing.decideInitialViewController(window: self.window!)
Otra solución al usar Swift 3 y Swift 4 para evitar el lanzamiento de fuerza es así
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 se utiliza 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, según los criterios que elija para un controlador de vista apropiado.
Además, no olvide agregar una identidad (seleccione guión gráfico -> Escena del controlador -> Mostrar el inspector de identidad -> asignar StorboardID).
RESPUESTA ACTUALIZADA para iOS 13 y delegado de escena:
asegúrese de que en su archivo info.plist vaya al Manifiesto de escena de aplicación -> Configuración de escena -> Rol de sesión de aplicación -> Elemento 0 y elimine la referencia al guión gráfico principal allí también. De lo contrario, recibirá la misma advertencia acerca de no crear una instancia del guión gráfico.
Además, mueva el código del delegado de la aplicación a la escena del método de delegado de escena (_: willConnectTo: opciones :), ya que aquí es donde se manejan los eventos del ciclo de vida.
Hace unos días me encontré con la misma situación. Un truco muy simple resolvió este problema. Puse oculto mi controlador de vista inicial antes del lanzamiento2. Si el controlador de vista inicial es el controlador correcto, se establece en visible en viewDidLoad. De lo contrario, se realiza una segue 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 de información del proyecto y usar makeKeyAndVisible
, simplemente coloque
self.window.rootViewController = rootVC;
en
- (BOOL) application:didFinishLaunchingWithOptions:
rootVC
a partir instantiateViewControllerWithIdentifier
, ¿correcto?
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 debe crear el objeto de su guión gráfico, luego cambiar la raíz (si es necesario) y luego tomar la referencia de un controlador de vista particular que se empuja al controlador de vista actual (si cambia la raíz) o simplemente presenta un nuevo controlador de vista que puede
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**
Swift 5 o superior # crea el controlador de vista de ruta con este código simple. Si está utilizando xcode 11 o superior, inicialice primero var window: UIWindow?
en AppDelegate
let rootVC = mainStoryboard.instantiateViewController(withIdentifier: "YOURCONTROLLER") as! YOURCONTROLLER
navigationController.setNavigationBarHidden(true, animated: true)
UIApplication.shared.windows.first?.rootViewController = UINavigationController.init(rootViewController: rootVC)
UIApplication.shared.windows.first?.makeKeyAndVisible()
Si prefiere no cambiar applicationDidFinish, puede hacer el siguiente truco:
Configure el controlador de navegación como un controlador de vista inicial y asígnele una clase personalizada 'MyNavigationController'. Luego puede ajustar su controlador de vista raíz durante viewDidLoad: anulará el controlador de vista raíz que configuró en su guión gráfico.
class MyNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
if !isLoggedIn() {
viewControllers = [R.storyboard.authentication.loginView()!]
}
}
private func isLoggedIn() -> Bool {
return false
}
}