iphone - Storyboard: consulte ViewController en AppDelegate
objective-c ios (3)
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 intento 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 documentation 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:
EDITADO para agregar código de ejemplo:
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard"
bundle: nil];
MyViewController *controller = (MyViewController*)[mainStoryboard
instantiateViewControllerWithIdentifier: @"<Controller ID>"];
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 pila, AppDelegate no debe estar llegando a la pila 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!
Si usa XCode
5, debe hacerlo de otra manera.
- Seleccione su
UIViewController
enUIStoryboard
- Vaya al
Identity Inspector
en el panel superior derecho - Marque la casilla de verificación
Use Storyboard ID
guionUse 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 (<your implementation>) {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main"
bundle: nil];
YourViewController *yourController = (YourViewController *)[mainStoryboard
instantiateViewControllerWithIdentifier:@"YourViewControllerID"];
self.window.rootViewController = yourController;
}
return YES;