cocoa touch - pagina - ¿Cómo descartar un modal que se presentó en un UIStoryboard con una transición modal?
popup al abrir pagina jquery (2)
Configuración: tengo un guión gráfico configurado, con dos controladores simples de vista A y B. Hay un botón en A, que pasa a B con una transición modal. B se presenta con una transición modal en la parte superior de A. Está bien.
Pregunta: ¿hay alguna manera de sacar a B y volver a A con un poco de magia simple del guión gráfico?
Tenga en cuenta que si todo esto estuviera en un controlador de navegación, y utilicé un segue de inserción, sería implícitamente atendido por el controlador de navegación. Habría un botón "atrás". No hay nada comparable para los modales, necesito construir la interfaz de usuario, lo cual está bien, pero me pregunto si existe una mecánica de segregación que pueda usar para indicar que vuelva de B a A.
Ahora el método oldskool para construir que va de B a A sería:
- crear una propiedad de delegado en B
- establecer A para ser el delegado de B cuando se reproduce la transición de transición modal (puedo conectarlo usando prepareForSegue: remitente: en el código de A)
- cuando es hora de despedir, B señala a su delegado
- A implementa un método delegado que descarta B
Esto funciona, pero se siente como demasiado alto y tonto.
¿Hay alguna mecánica de UIStoryboard que me haya perdido, que básicamente haría una "transición modal inversa"?
Hay magia del guión gráfico para lograr esto. Es conocido como un segue de desenrollar. En el archivo .h de A, implemente los métodos de estilo de "acción de destino" que necesite para cuantos segmentos de desenrollado necesite. Para un modal, por lo general es dos (cancelar y guardar). Entonces, en mi archivo Ah, agregaría:
// A.h file
- (IBAction)myCancelUnwindSegueCallback:(UIStoryboardSegue *)segue;
- (IBAction)mySaveUnwindSegueCallback:(UIStoryboardSegue *)segue;
Ahora, en su guión gráfico, si tiene una transición de A a B. Ahora puede hacer un arrastre de control de estilo de "acción de destino" desde los botones de cancelar / guardar en B hasta el icono verde de "Salir" en la parte inferior del controlador B en tu guión gráfico Cuando hagas esto, Xcode recogerá los dos métodos que creamos (ya que están en el archivo de encabezado de A y tienen la firma correcta (por ejemplo, IBAction y UIStoryboardSegue *.) Y B es el destino de una transición de A). ahí tienes. ¡Tienes la magia del guión gráfico que estabas buscando!
En la implementación de las dos devoluciones de llamada, tendría algo como:
// A.m file
- (IBAction)myCancelUnwindSegueCallback:(UIStoryboardSegue *)segue {
UIViewController *modalGoingAway = segue.sourceViewController;
// Do something (like get data) from modalGoingAway if you need to...
}
- (IBAction)mySaveUnwindSegueCallback:(UIStoryboardSegue *)segue {
UIViewController *modalGoingAway = segue.sourceViewController;
// Do something (like get data) from modalGoingAway if you need to...
}
Por último, si este enfoque satisface tus necesidades, genial. Ya terminaste Sin embargo, todavía cableo el patrón de diseño delegado / fuente de datos del protocolo completo si "on cancel" o "on save" deseo realizar algunas operaciones en las propiedades privadas de B antes de pasar el control a A para eliminar B de la jerarquía de vista.
No hay ninguna magia del guión gráfico para descartar un controlador de vista modal sin escribir al menos un poquito de código.
Pero si bien tiene que implementar algún código propio, no necesariamente tiene que tomarse tantas molestias. Solo puede tener un botón en el controlador de vista B que llame [self dismissViewControllerAnimated:YES completion:nil]
. (Los documentos dicen que el controlador de visualización de presentación debe ser el que se descarta, pero también dicen que el mensaje se reenviará al controlador de vista de presentación si se llama al presente. Si quieres ser más explícito al respecto, y tú " Necesitaré serlo en algunos casos, como cuando un controlador de vista modal se presenta desde otro: puede hacer referencia explícita al presentador con self.presentingViewController
y call self.presentingViewController
dismiss...
desde allí).
Verá el negocio de delegados en algunas aplicaciones porque es una forma de notificar al controlador de vista A sobre lo que hizo el usuario mientras estaba en el controlador de vista B ... pero no es la única manera. Hay KVO, notificaciones, o simplemente llamando a los métodos de A después de hacer referencia a él con self.presentingViewController
(suponiendo que B sabe que siempre se presenta por A). Y si A no necesita saber lo que sucedió en B (digamos, porque el usuario pulsa el botón Cancelar), no hay necesidad de hacer nada de eso; simplemente puede descartar el modal y terminarlo.
En iOS 6 y versiones posteriores, los segmentos de desenrollo agregan otra opción, proporcionando un poco de "magia del guión gráfico" para descartar los controladores de vista modal (o de lo contrario "anular" una secuencia de segues). Pero este enfoque aún requiere un código: no se puede configurar por completo en el guión gráfico. En el lado positivo, sin embargo, ese código proporciona una ruta para obtener información del controlador de vista que se descarta (B) a la que lo presentó (A).
Apple tiene una nota técnica sobre los segmentos de desenrollado que los cubre en detalle, pero aquí está la versión corta:
Defina un método
IBAction
en la clase de controlador de vista que desea desenrollar, la que presenta un controlador de vista modal, no el controlador de vista modal en sí (vea el controlador A en su pregunta). A diferencia de los métodosIBAction
normales, estos deben tomar un parámetro de tipoUIStoryboardSegue *
; p.ej- (IBAction)unwindToMainMenu:(UIStoryboardSegue*)sender
En el controlador de vista presentado (B en la pregunta), conecte un control al icono de Salida verde y elija el método que definió.
En la implementación de su método de desenrollado, puede consultar
sourceViewController
de segue para recuperar información del controlador de vista que se está descartando. No es necesario quedismissViewControllerAnimated:completion:
porque el segue trata de descartar el controlador de vista que se va.