Al descartar un controlador de vista modal mediante dismissViewController
, existe la opción de proporcionar un bloque de finalización. ¿Existe un equivalente similar para popViewController
?
El argumento de la finalización es bastante útil. Por ejemplo, puedo usarlo para retrasar la eliminación de una fila de una vista de tabla hasta que el modal esté fuera de la pantalla, lo que permite al usuario ver la animación de la fila. Al regresar de un controlador de vista empujado, me gustaría tener la misma oportunidad.
He intentado colocarlo popViewController
en un UIView
bloque de animación, donde tengo acceso a un bloque de finalización. Sin embargo, esto produce algunos efectos secundarios no deseados en la vista que se abre.
Si no existe tal método disponible, ¿cuáles son algunas soluciones?
fuente
Respuestas:
Sé que se aceptó una respuesta hace más de dos años, sin embargo, esta respuesta está incompleta.
Esto es técnicamente correcto porque la
UINavigationController
API no ofrece ninguna opción para esto. Sin embargo, al usar el marco CoreAnimation, es posible agregar un bloque de finalización a la animación subyacente:El bloque de finalización se llamará tan pronto como
popViewControllerAnimated:
finalice la animación utilizada por . Esta funcionalidad está disponible desde iOS 4.fuente
extension UINavigationController { func popViewControllerWithHandler(handler: ()->()) { CATransaction.begin() CATransaction.setCompletionBlock(handler) self.popViewControllerAnimated(true) CATransaction.commit() } }
Para la versión SWIFT de iOS9 : funciona como un encanto (no había probado para versiones anteriores). Basado en esta respuesta
fuente
Hice una
Swift
versión con extensiones con la respuesta de @JorisKluivers .Esto llamará un cierre de finalización después de que se complete la animación para ambos
push
ypop
.fuente
popViewController
opushViewController
, pero si comprueba qué es el topViewController justo después, notará que sigue siendo el anterior, comopop
opush
nunca sucedió ...SWIFT 4.1
fuente
Tuve el mismo problema. Y como tuve que usarlo en múltiples ocasiones, y dentro de cadenas de bloques de finalización, creé esta solución genérica en una subclase UINavigationController:
Asumiendo
y
y
fuente
No hay forma de hacer lo que desea de inmediato. es decir, no existe un método con un bloque de finalización para extraer un controlador de vista de una pila de navegación.
Lo que haría es poner la lógica
viewDidAppear
. Se llamará cuando la vista haya terminado de aparecer en pantalla. Se llamará para todos los escenarios diferentes del controlador de vista que aparecen, pero eso debería estar bien.O puede usar el
UINavigationControllerDelegate
métodonavigationController:didShowViewController:animated:
para hacer algo similar. Esto se llama cuando el controlador de navegación ha terminado de presionar o abrir un controlador de vista.fuente
dismissViewController
. Tal vez se recuperepopViewController
. Presentar un radar :-).-dismissViewController:animated:completionBlock:
, puede obtener la animación a través del delegado del controlador de navegación. Una vez completada la animación,-navigationController:didShowViewController:animated:
se llamará al delegado y podrá hacer lo que necesite allí mismo.Trabajar con o sin animación correctamente, y también incluye
popToRootViewController
:fuente
completion()
async?completion
nunca se ejecuta en el mismo runloop. esto garantiza quecompletion
nunca se ejecute en el mismo runloop cuando no esté animando. es mejor no tener este tipo de inconsistencias.Basado en la respuesta de @ HotJard, cuando todo lo que quieres son solo un par de líneas de código. Rapido y Facil.
Rápido 4 :
fuente
Para 2018 ...
si tienes esto ...
y desea agregar una finalización ...
Es así de simple.
Consejo útil ...
Es el mismo trato para la
popToViewController
llamada práctica .Una cosa típica es que tiene una pila de incorporación de un trillón de pantallas. Cuando finalmente haya terminado, regrese a la pantalla "base" y, finalmente, inicie la aplicación.
Por lo tanto, en la pantalla "base", para "retroceder completamente",
popToViewController(self
fuente
El bloque de finalización se llama después de llamar al método viewDidDisappear en el controlador de vista presentado, por lo que poner código en el método viewDidDisappear del controlador de vista emergente debería funcionar igual que un bloque de finalización.
fuente
Respuesta rápida 3, gracias a esta respuesta: https://stackoverflow.com/a/28232570/3412567
fuente
Versión Swift 4 con el parámetro viewController opcional para pasar a uno específico.
fuente
Se limpió la versión de Swift 4 basada en esta respuesta .
fuente
Hay un pod llamado UINavigationControllerWithCompletionBlock que agrega soporte para un bloque de finalización al presionar y hacer estallar un UINavigationController.
fuente
2020 Swift 5.1 forma
Esta solución garantiza que la finalización se ejecute después de que popViewController esté completamente terminado. Puede probarlo haciendo otra operación en NavigationController al finalizar: en todas las demás soluciones anteriores, UINavigationController todavía está ocupado con la operación popViewController y no responde.
fuente
Solo para completar, he creado una categoría Objective-C lista para usar:
fuente
Logré exactamente esto con precisión usando un bloque. Quería que mi controlador de resultados obtenido mostrara la fila que fue agregada por la vista modal, solo una vez que haya abandonado completamente la pantalla, para que el usuario pueda ver el cambio. En preparación para segue, que es responsable de mostrar el controlador de vista modal, configuro el bloque que quiero ejecutar cuando el modal desaparece. Y en el controlador de vista modal anulo viewDidDissapear y luego llamo al bloque. Simplemente comienzo las actualizaciones cuando va a aparecer el modal y finalizo las actualizaciones cuando desaparece, pero eso se debe a que estoy usando un NSFetchedResultsController, sin embargo, puede hacer lo que quiera dentro del bloque.
fuente
Use la siguiente extensión en su código: (Swift 4)
fuente