Estoy a punto de crear una aplicación usando un UINavigationControllerpara presentar los siguientes controladores de vista. Con iOS5 hay un nuevo método de presentación UIViewControllers:
presentViewController:animated:completion:
Ahora me pregunto por qué no hay un controlador de finalización para UINavigationController. Hay solo
pushViewController:animated:
¿Es posible crear mi propio controlador de finalización como el nuevo presentViewController:animated:completion:?

viewDidAppear:animated:permite ejecutar código cada vez que su controlador de vista aparece en la pantalla (viewDidLoadsolo la primera vez que se carga su controlador de vista)-(void)viewDidAppear:(BOOL)animatedRespuestas:
Vea la respuesta de par para otra solución más actualizada
UINavigationControllerLas animaciones se ejecutan conCoreAnimation, por lo que tendría sentido encapsular el código dentroCATransactiony así establecer un bloque de finalización.Rápido :
Para ser rápido, sugiero crear una extensión como tal
Uso:
C objetivo
Encabezamiento:
Implementación:
fuente
pushViewController:animated:opopViewController:animated, las llamadasviewDidLoadyviewDidAppearocurren en ciclos de ejecución posteriores. Entonces, mi impresión es que incluso si esos métodos invocan animaciones, no serán parte de la transacción proporcionada en el ejemplo de código. ¿Era ésa tu preocupación? Porque esta solución es fabulosamente simple.didShowViewControllerembargo, está garantizado que el controlador de vista en cuestión se muestra . Si bien esta solución es fantásticamente simple, cuestionaría su "capacidad para el futuro". Especialmente dados los cambios para ver las devoluciones de llamada del ciclo de vida que vinieron con ios7 / 8iOS 7+ Swift
Rápido 4:
EDITAR: agregué una versión Swift 3 de mi respuesta original. En esta versión, eliminé la co-animación de ejemplo que se muestra en la versión Swift 2, ya que parece haber confundido a mucha gente.
Swift 3:
Rápido 2:
fuente
nilcomo bloque de animación.niles algo perfectamente válido para hacer también.transitionCoordinatores nulo?transitionCoordinator, es probable que esté llamando a esta función demasiado pronto en el ciclo de vida del controlador de navegación. Espere al menos hasta queviewWillAppear()se llame antes de intentar presionar un controlador de vista con animación.Basado en la respuesta de par (que fue la única que funcionó con iOS9), pero más simple y con un else (lo que podría haber llevado a que nunca se llamara a la finalización):
fuente
Actualmente, el
UINavigationControllerno admite esto. Pero está elUINavigationControllerDelegateque puedes usar.Una manera fácil de lograr esto es subclasificar
UINavigationControllery agregar una propiedad de bloque de finalización:Antes de presionar el nuevo controlador de vista, tendría que establecer el bloque de finalización:
Esta nueva subclase puede asignarse en Interface Builder o usarse programáticamente de esta manera:
fuente
pushViewController:animated:completion:lo convertiría en una solución elegante.Aquí está la versión Swift 4 con Pop.
En caso de que alguien más lo necesite.
fuente
Para ampliar la respuesta de @Klaas (y como resultado de esta pregunta) agregué bloques de finalización directamente al método push:
Para ser utilizado de la siguiente manera:
fuente
if... (self.pushedVC == viewController) {Es incorrecto. Necesita probar la igualdad entre objetos usandoisEqual:, es decir,[self.pushedVC isEqual:viewController]isEqualprobablemente sería más técnicamente correcto en caso de que alguna vez lo hicieran.Desde iOS 7.0, puede usar
UIViewControllerTransitionCoordinatorpara agregar un bloque de finalización de inserción:fuente
Swift 2.0
fuente
Se necesita un poco más de trabajo para agregar este comportamiento y conservar la capacidad de establecer un delegado externo.
Aquí hay una implementación documentada que mantiene la funcionalidad de delegado:
LBXCompletingNavigationController
fuente