Storyboard: consulte ViewController en AppDelegate

considere la siguiente situación: Tengo una aplicación basada en un guión gráfico. Agrego un objeto ViewController al guión gráfico, agrego los archivos de clase para este ViewController al proyecto y especifico el nombre de la nueva clase en el inspector de identidad del IB. Ahora, ¿cómo voy a referirme a este ViewController programáticamente desde AppDelegate? Creé una variable con la clase relevante y la convertí en una propiedad IBOutlet, pero no veo ninguna forma de poder referirme al nuevo ViewController en el código; cualquier bash de arrastrar y arrastrar una conexión no funciona .

es decir, dentro de AppDelegate puedo acceder al ViewController de base como este

(MyViewController*) self.window.rootViewController 

pero ¿qué hay de cualquier otro ViewController contenido en el guión gráfico?

Eche un vistazo a la documentación para -[UIStoryboard instantiateViewControllerWithIdentifier:] . Esto le permite crear una instancia de un controlador de vista desde su guión gráfico usando el identificador que estableció en el Inspector de atributos de IB:

enter image description here

EDITADO para agregar código de ejemplo:

 UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle: nil]; MyViewController *controller = (MyViewController*)[mainStoryboard instantiateViewControllerWithIdentifier: @""]; 

Si usa XCode 5, debe hacerlo de otra manera.

  • Seleccione su UIViewController en UIStoryboard
  • Vaya al Identity Inspector en el panel superior derecho
  • Marque la checkbox Use Storyboard ID guion Use Storyboard ID
  • Escriba una identificación única en el campo Storyboard ID

Luego escribe tu código.

 // Override point for customization after application launch. if () { UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil]; YourViewController *yourController = (YourViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:@"YourViewControllerID"]; self.window.rootViewController = yourController; } return YES; 

Generalmente, el sistema debe manejar la instanciación del controlador de vista con un guión gráfico. Lo que desea es atravesar la jerarquía viewController al tomar una referencia al self.window.rootViewController en lugar de inicializar los controladores de vista, que ya deberían inicializarse correctamente si configuró su guión gráfico correctamente.

Entonces, digamos que su rootViewController es un UINavigationController y luego desea enviar algo a su controlador de vista superior, lo haría así en el didFinishLaunchingWithOptions su AppDelegate:

 UINavigationController *nav = (UINavigationController *) self.window.rootViewController; MyViewController *myVC = (MyViewController *)nav.topViewController; myVC.data = self.data; 

En Swift si sería muy similar:

 let nav = self.window.rootViewController as! UINavigationController; let myVC = nav.topViewController as! MyViewController myVc.data = self.data 

En realidad, no debería inicializar los controladores de vista con ID de storyboard del delegado de la aplicación, a menos que desee omitir el guión gráfico normal y cargar todo el guion gráfico usted mismo. Si tiene que inicializar escenas de AppDelegate, lo más probable es que esté haciendo algo mal. Me refiero a que, por alguna razón, quiera enviar datos a un controlador de vista en la stack, AppDelegate no debe estar llegando a la stack del controlador de vista para establecer los datos. Ese no es asunto suyo. Sus negocios son los rootViewController. Deje que el controlador rootView maneje sus propios hijos. Por lo tanto, si el sistema omitiera el proceso normal de carga del guión gráfico al eliminar las referencias al mismo en el archivo info.plist, como máximo instanciaría el RootViewController utilizando instantiateViewControllerWithIdentifier: y posiblemente su raíz si es un contenedor, como un UINavigationController . Lo que desea evitar es crear instancias de controladores de vista que ya hayan sido instanciados por el guión gráfico. Este es un problema que veo mucho. En resumen, no estoy de acuerdo con la respuesta aceptada. Es incorrecto a menos que los carteles signifiquen eliminar la carga del guión gráfico de info.plist ya que de lo contrario habrá cargado 2 guiones gráficos, lo que no tiene sentido. Probablemente no sea una pérdida de memoria porque el sistema inicializó la escena raíz y la asignó a la ventana, pero luego apareciste y la volviste a crear y volvió a asignarla. ¡Tu aplicación ha tenido un comienzo bastante malo!