Estoy a punto de crear una aplicación usando un UINavigationController
para 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 (viewDidLoad
solo la primera vez que se carga su controlador de vista)-(void)viewDidAppear:(BOOL)animated
Respuestas:
Vea la respuesta de par para otra solución más actualizada
UINavigationController
Las animaciones se ejecutan conCoreAnimation
, por lo que tendría sentido encapsular el código dentroCATransaction
y 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 llamadasviewDidLoad
yviewDidAppear
ocurren 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.didShowViewController
embargo, 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
nil
como bloque de animación.nil
es algo perfectamente válido para hacer también.transitionCoordinator
es 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
UINavigationController
no admite esto. Pero está elUINavigationControllerDelegate
que puedes usar.Una manera fácil de lograr esto es subclasificar
UINavigationController
y 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]
isEqual
probablemente sería más técnicamente correcto en caso de que alguna vez lo hicieran.Desde iOS 7.0, puede usar
UIViewControllerTransitionCoordinator
para 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