objective c - prepareForSegue no se llama después de performSegue: withIdentifier: con estilo popover
objective-c ipad (2)
Lo que he descubierto hasta ahora es que con cualquier identificador de segue que no sea popover, estas son las invocaciones hechas por iOS:
- prepareForSegue (en el controlador de origen)
- viewDidLoad (en el controlador de destino)
mientras que en popover segue el orden de invocación es:
- viewDidLoad (en el controlador de destino)
- prepareForSegue (en el controlador de origen)
solo porque puse toda mi lógica en viewDidLoad, el controlador no se inicializó correctamente y se produjo un bloqueo. Así que esto no es exactamente cierto que prepareForSegue no se llame, la verdad es que recibí una excepción, y erróneamente me equivoqué al decir que prepareForSegue no recibe una llamada.
No pude poner todo a la vista WillAppear porque tuve que hacer una llamada a CoreData y no quería verificar si las entidades estaban bien cada vez que se mostraba la vista.
¿Cómo resolví esto? Creé otro método en el controlador de destino
-(void)prepareViewController {
// initialization logic...
}
y cambiando el método prepareForSegue en el controlador de origen en sí:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
MyViewController *mvc = (MyViewController*)[segue destinationViewController];
// passing variable
// with segue style other than popover this called first than viewDidLoad
mvc.myProp1=@"prop1";
mvc.myProp2=@"prop2";
// viewWillAppear is not yet called
// so by sending message to controller
// the view is initialized
[mvc prepareViewController];
}
No sé si este es el comportamiento esperado con Popover, de todos modos ahora las cosas están funcionando.
Tengo una aplicación universal, donde estoy compartiendo el mismo controlador para un guión gráfico de IPad e iPhone. He puesto un UILongPressGestureRecognizer en una UITableView, que cuando se presiona una celda en iPhone llama a una acción que realiza una segue:
-(IBAction)showDetail:(id)sender {
UILongPressGestureRecognizer *gesture = (UILongPressGestureRecognizer*)sender;
if (gesture.state == UIGestureRecognizerStateBegan) {
CGPoint p = [gesture locationInView:self.theTableView];
NSIndexPath *indexPath = [self.theTableView indexPathForRowAtPoint:p];
if (indexPath != nil) {
[self performSegueWithIdentifier:SEGUE_DETAIL sender:indexPath];
}
}
}
el segue es una vista detallada realizada como un ''push''. Lo primero que debe observar es que el remitente es un NSIndexPath, es la única forma que encontré para pasar la celda seleccionada. Tal vez hay una mejor solución. Todo funciona bien, en el sentido de que se realiza la transición y antes de que también se llame a prepareForSegue.
Sin embargo, sucede que en el iPad, he cambiado el identificador de segue a Popover. Ahora las cosas están funcionando en parte, se realiza la transición, pero no se llama a prepareForSegue y, por lo tanto, el controlador de vista de destino no está configurado como debería ser.
Qué estoy haciendo mal ?
Me he dado cuenta de que el código de la placa de la caldera para la plantilla de detalles maestros de Xcode (iPhone) usa el siguiente patrón para configurar la vista detallada de VC:
- el detalle Los ajustadores de VC (para propiedades) se sobrescriben para invocar el método configureView (configureView actualizaría todos sus controles en la vista, por ejemplo, etiquetas, etc.)
- el detalle El método viewDidLoad de VC también invoca el método configureView
No seguí este patrón el otro día cuando estaba tratando de volver a utilizar un detalle de VC en mi aplicación de película, y esto me dio problemas.
No tengo mucha experiencia con popovers; sin embargo, si el patrón anterior se usa con un VC detallado que se muestra dentro de un popover, ¿no se configuraría la vista de VC detallada cuando se configuran las propiedades detalladas de VC dentro del método prepareForSegue?