Animar el cambio de text del título de la barra de navigation

En mi aplicación, tengo un controller de vista de página que permite al usuario deslizar entre diferentes "secciones" de la aplicación y, en la parte superior de la barra de navigation, cambio el text del título a la nueva sección que el usuario ha pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted: a través de pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted: Actualmente, el text del título cambia instantáneamente cuando se completa la animation. Me gustaría mejorar esto con algo de animation, un sutil efecto de desvanecimiento de input y salida.

Primero traté de implementar [UIView animationWithDuration:...] para animar a cambiar el text del título, pero no hace animation y simplemente se actualiza al instante.

Luego me pregunté si sería posible actualizar el alfa del título de la barra de navigation a medida que el usuario se desplaza horizontalmente en function de cuánto han desplazado, llegando a 0 alfa cuando la próxima sección está por aparecer en la pantalla, entonces puedo instantáneamente cambie el text mientras está en 0 y luego desvanezca rápidamente en 1 alfa. Pero no veo un método en UIPageViewControllerDelegate que se UIPageViewControllerDelegate cuando se actualiza la position de desplazamiento.

Si es posible, en lugar de simplemente desvanecerse, podría desvanecerse y mover la position del text del título en la barra de navigation como la animation pnetworkingeterminada que se produce cuando se navega hacia atrás desde un segue de empuje mediante un gesto de deslizar. Deslizaré el título de la sección anterior a medida que el usuario se desplaza y proporcionaré el título de la siguiente sección en el otro lado, de modo que cuando la transición finalice, el título de la sección anterior quede desactivado y el nuevo esté perfectamente centrado para que se complete el reemploop. Pero nuevamente, esto requiere saber exactamente cuánto ha desplazado el usuario al controller de vista de página.

¿Es posible implementar alguna de las animaciones deseadas?

Si desea animar entre diferentes cadenas de títulos, use lo siguiente:

 CATransition *fadeTextAnimation = [CATransition animation]; fadeTextAnimation.duration = 0.5; fadeTextAnimation.type = kCATransitionFade; [self.navigationController.navigationBar.layer addAnimation: fadeTextAnimation forKey: @"fadeText"]; self.navigationItem.title = "My new title"; 

Puede ajustar la duración y establecer una function de synchronization para adaptarse, por supuesto.

También hay otros types de animation que pueden funcionar en diferentes circunstancias (gracias @inorganik):

 kCATransitionFade kCATransitionMoveIn kCATransitionPush kCATransitionReveal 

Para mayor comodidad, la solución Ashley Mills en Swift:

11/16/2016 Actualizado para Swift 3 (Gracias a n13)

 let fadeTextAnimation = CATransition() fadeTextAnimation.duration = 0.5 fadeTextAnimation.type = kCATransitionFade navigationController?.navigationBar.layer.add(fadeTextAnimat‌​ion, forKey: "fadeText") navigationItem.title = "test 123" 

Swift 2.x

 let fadeTextAnimation = CATransition() fadeTextAnimation.duration = 0.5 fadeTextAnimation.type = kCATransitionFade navigationController?.navigationBar.layer.addAnimation(fadeTextAnimation, forKey: "fadeText") navigationItem.title = "test 123" 

¡Le doy mi sombrero a Ashley!

Una solución es crear un título personalizado y animar su position utilizando el método de delegado oculto de scrollView del controller de vista de página. Como dijo Zhang, el título personalizado es simplemente self.navigationItem.titleView = customNavTitleLabel;

Encontramos que la mejor forma es esta categoría:

 @implementation UIViewController (ControllerNavigationEffects) -(void) setNavigationTitleWithAnimation:(NSString *) title { if ([self.navigationItem.title isEqualToString:title]) { return; } @weakify(self); float duration = 0.2; [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ @strongify(self); self.navigationItem.titleView.alpha = 0; } completion:^(BOOL finished) {}]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ @strongify(self); self.navigationItem.titleView = nil; self.navigationItem.title = title; [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ self.navigationItem.titleView.alpha = 1; } completion:nil]; }); } -(void) setNavigationTitleViewWithAnimation:(UIView *) titleView { if ([self.navigationItem.titleView isKindOfClass:[titleView class]]) { return; } @weakify(self); float duration = 0.2; CATransition *fadeTextAnimation = [CATransition animation]; fadeTextAnimation.duration = duration; fadeTextAnimation.type = kCATransitionFade; [self.navigationController.navigationBar.layer addAnimation: fadeTextAnimation forKey: @"fadeText"]; self.navigationItem.title = @""; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ @strongify(self); self.navigationItem.title = @""; self.navigationItem.titleView = titleView; [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ self.navigationItem.titleView.alpha = 1; } completion:nil]; }); }