Así. Acaba de comenzar la transición de mi código de IOS de IOS7, y se topó con un poco de problema.

Tengo un UINavigationController, que tiene hijo ViewControllers y estoy usando pushViewController para mostrar el siguiente vistas. Para crear un paralaje de animación con un conjunto de imágenes, si ha personalizado el UINavigationController para animar un conjunto de UIImageViews y mi hijo ViewControllers todos tienen un self.backgroundColor = [UIColor clearColor], la transparencia.

Desde iOS7, la forma en que el UINavController anima niño vc, se actualiza, en parte por el movimiento de la vista actual del controlador y en la parte superior empujando el nuevo viewcontroller, mi paralaje de la animación se ve una mierda. Veo que la anterior VC mover un poco y luego desaparecen. Hay alguna manera de que pueda restaurar la anterior UINavigationController pushViewController de la animación? Me parece que no puede encontrar esto en el código.

WelcomeLoginViewController* welcomeLoginViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"WelcomeLogin"];
    [self.navigationController pushViewController:welcomeLoginViewController animated:YES];    

Incluso trató de usar:

    [UIView animateWithDuration:0.75
                     animations:^{
                         [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
                         [self.navigationController pushViewController:welcomeLoginViewController animated:NO];
                         [UIView setAnimationTransition:<specific_animation_form> forView:self.navigationController.view cache:NO];
                     }];

¿Alguien tiene alguna pista?

  • Para el registro, el stock de animación (me.e el empuje recta con animación:SÍ) presenta el mismo comportamiento ahora.

9 Comentarios

  1. 46

    Me las arreglé para la solución del nuevo tipo de transición mediante la creación de una categoría para UINavigationController. En mi caso necesitaba para volver al viejo estilo de transición porque he transparente viewControllers que se deslizan sobre un fondo estático.

    • UINavigationController+Retro.h

      @interface UINavigationController (Retro)
      
      - (void)pushViewControllerRetro:(UIViewController *)viewController;
      - (void)popViewControllerRetro;
      
      @end
    • UINavigationController+Retro.m

      #import "UINavigationController+Retro.h"
      
      @implementation UINavigationController (Retro)
      
      - (void)pushViewControllerRetro:(UIViewController *)viewController {
          CATransition *transition = [CATransition animation];
          transition.duration = 0.25;
          transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
          transition.type = kCATransitionPush;
          transition.subtype = kCATransitionFromRight;
          [self.view.layer addAnimation:transition forKey:nil];
      
          [self pushViewController:viewController animated:NO];
      }
      
      - (void)popViewControllerRetro {
          CATransition *transition = [CATransition animation];
          transition.duration = 0.25;
          transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
          transition.type = kCATransitionPush;
          transition.subtype = kCATransitionFromLeft;
          [self.view.layer addAnimation:transition forKey:nil];
      
          [self popViewControllerAnimated:NO];
      }
      
      @end
    • Hola Arne, Gracias por tu solución. Sin embargo la animación de la UINavigationController la vista, en lugar de que el niño vistas de la controladora. De esa manera, la barra de navegación exhibe un comportamiento diferente. Trató de problemas a través de la creación de un completo animaciones personalizadas de ambos puntos de vista, pero todavía no se obtiene el efecto deseado.
    • Gracias, esto funciona para mí. Sin embargo, cuando el usuario pulsa el botón Volver, se vuelve a la busted animación (debido a que el botón atrás no llame popViewControllerRetro).
    • Cuenta, usted puede reemplazar el botón atrás con leftBarButtonItem. Elegí la transición.duración = 0.4 porque parecía estar más cerca de la edad de velocidad, al menos en el Xcode simuladores.
    • Esto hizo que el truco para mí – yo también tuve un viewcontroller con fondo transparente de ser empujado en NavigationController con fondo transparente y una imagen de fondo. El nuevo iOS7 transición se veía como una mierda, me pregunto por qué Apple no acaba de agregar estas nuevas funciones «en silencio», sin «fuerza bruta hacer valer» los cambios a la interfaz de usuario nativa de comportamiento que nos da un montón de problemas y dolores de cabeza!
    • Esto funcionó de maravilla para mí. Yo estaba usando clearColor para mi viewControllers (con el fin de obtener una animación suave debajo de UIWindow subvistas), pero tengo un molesto al azar tartamudear hasta la aplicación de esta.
    • Bien hecho! Hice el truco para mí también!
    • Compruebe mi respuesta a continuación.
    • Usted es un protector de la vida tio. Esto funcionó muy bien para mí, muchas gracias!!!!.
    • Gracias por este gran solución… me di cuenta de una cosa , cuando me llaman pushViewControllerRetro con el tiempo de intervalo de 0.4 puedo ver de color negro mientras que la de la transición. Alguno vio este comportamiento ? También simple popViewControler:animación funciona para mí. Así que todavía necesito para usar popViewControllerRetro ? Gracias
    • Esto es muy bueno! Salvó un montón de dolores de cabeza 😀
    • Estoy viendo la misma cosa! Los colores blanco y negro… alguien una solución?
    • No me dieron solución
    • Creo que debemos crear una nueva pregunta para que… Después de que se ralentice a alrededor de 1 seg, he descubierto que es porque el viejo VC parpadea en blanco y el nuevo también. Check it out. Por casualidad, ¿usted encontrar alguna otra solución?
    • He encontrado la solución. Lo que yo y probablemente lo hizo, es añadir una capa de fondo para la UINavigationController [_navController.view insertSubview:_someSubview atIndex:0]; … Ahora lo que quiero hacer es agregar el fondo de la vista a la UIWindow como una subvista lugar… [self.window addSubview:_someView]; y llame a [self.view setBackgroundColor:[UIColor clearColor]]; en cada viewDidAppear de la UIViewController de ser empujado. Funciona de maravillas! 🙂

  2. 22

    Tengo el mismo problema con el fondo claro de colores y animaciones de mierda, así que me cree la transición para ViewController con el nuevo iOS7 API. Todo lo que necesita es simplemente establecer un delegado para su navegación controlador:

    //NavigationController does not retain delegate, so you should hold it.
    self.navigationController.delegate = self.navigationTransitioningDelegate;

    Añadir archivos a su proyecto: MGNavigationTransitioningDelegate.

    • Trabajo increíble, ya esta resuelto el problema para mí.
    • Yep. Increíble!!!
    • Increíble! La mejor solución
    • Hermoso Solución!
    • Funciona como un encanto! Gracias!
    • Muy útil! Gracias!
    • Desafortunadamente, esta solución se rompe el diseño automático – cuando se gira y volver a las opiniones están todos rotos en la página anterior hasta que girar de nuevo.
    • Buena solución. Hice Swift 3 versión de su esencia: gist.github.com/steryokhin/f136bd3e0c38b0fcdbff30b311714257
    • Tal vez esto ayudaría gist.github.com/ArtFeel/7690431#gistcomment-1912196

  3. 18

    Tuve un problema en cuando Un UIViewController hizo un pushViewController para empujar UIViewController B, el empuje de la animación se detiene en aproximadamente un 25%, detener y, a continuación, deslice B en el resto del camino.

    Esto NO sucede en iOS 6, pero tan pronto como empecé a usar iOS 7 como el SDK base en XCode 5, esto comenzó a suceder.

    La revisión es que la vista controlador B no tienen un fondo establecido en la raíz de la vista (la raíz punto de vista es el que es el valor de viewController.la vista, que se establece normalmente en loadView). Establecimiento de un fondo en el que la raíz de la vista de inicializador se ha solucionado el problema.

    He conseguido solucionar esto de la siguiente manera:

    //CASE 1: The root view for a UIViewController subclass that had a halting animation
    
    - (id)initWithFrame:(CGRect)frame
    
    {
    
         if ((self = [super initWithFrame:frame])) {
    
              //Do some initialization ...
    
              //self.backgroundColor was NOT being set
    
              //and animation in pushViewController was slow and stopped at 25% and paused
    
         }
    
         return self;
    
    }
    
    //CASE 2: HERE IS THE FIX
    
    - (id)initWithFrame:(CGRect)frame
    
    {
    
         if ((self = [super initWithFrame:frame])) {
    
              //Do some initialization ...
    
              //Set self.backgroundColor for the fix!
    
              //and animation in pushViewController is no longer slow and and no longer stopped at 25% and paused
    
              self.backgroundColor = [UIColor whiteColor]; //or some other non-clear color
    
         }
    
         return self;
    
    }
    • Estoy teniendo exactamente el mismo problema, pero por desgracia mi punto de vista B ha clearColor, acabo de agregar exactamente la misma imagen de fondo como yo.parentViewController.vista.xxxxxx y ahora funciona… gracias!
    • Sí, este es exactamente solucionado el problema. Gracias!
    • Loco solución. Trabajó para mí también !
    • ¿Cómo se consigue eso? yo podría haber intentado Vudú lugar..gracias
  4. 7

    Primero de todo, yo no estoy usando el Storyboard. He intentado utilizar UINavigationController+Retro. Por alguna razón, el UINavigationController está teniendo un momento difícil soltar el UIViewController en la parte superior de la pila. Aquí está la solución que me funciona con iOS 7 de transición personalizado.

    1. Conjunto delegado a sí mismo.

      navigationController.delegate = self;
    2. Declarar este UINavigationControllerDelegate.

      - (id<UIViewControllerAnimatedTransitioning>)navigationController (UINavigationController *)navigationController 
      animationControllerForOperation:(UINavigationControllerOperation)operation
      fromViewController:(UIViewController *)fromVC 
      toViewController:(UIViewController *)toVC 
      {
          TransitionAnimator *animator = [TransitionAnimator new]; 
          animator.presenting = YES;
          return animator;
      }

      Tenga en cuenta que sólo se llama cuando la animación está establecida en SÍ. Por ejemplo

      [navigationController pushViewController:currentViewController animated:YES];
    3. Crear el animador de la ampliación de la clase NSObject. Me llama la mina TransitionAnimator, el cual fue modificado a partir de TeehanLax del TLTransitionAnimator dentro de UIViewController-Transiciones-Ejemplo.

      TransitionAnimator.h

      #import <Foundation/Foundation.h>
      @interface TransitionAnimator : NSObject <UIViewControllerAnimatedTransitioning>
      @property (nonatomic, assign, getter = isPresenting) BOOL presenting;
      @end

      TransitionAnimator.m

      #import "TransitionAnimator.h"
      @implementation TransitionAnimator
      - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
          return 0.5f;
      }
      - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{
          UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
          UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];    
          if (self.presenting) {
              //ANIMATE VC ENTERING FROM THE RIGHT SIDE OF THE SCREEN
              [transitionContext.containerView addSubview:fromVC.view];
              [transitionContext.containerView addSubview:toVC.view];     
              toVC.view.frame = CGRectMake(0, 0, 2*APP_W0, APP_H0); //SET ORIGINAL POSITION toVC OFF TO THE RIGHT                
              [UIView animateWithDuration:[self transitionDuration:transitionContext] 
                  animations:^{
                      fromVC.view.frame = CGRectMake(0, (-1)*APP_W0, APP_W0, APP_H0); //MOVE fromVC OFF TO THE LEFT
                      toVC.view.frame = CGRectMake(0, 0, APP_W0, APP_H0); //ANIMATE toVC IN TO OCCUPY THE SCREEN
                  } completion:^(BOOL finished) {
                      [transitionContext completeTransition:YES];
                  }];
          }else{
              //ANIMATE VC EXITING TO THE RIGHT SIDE OF THE SCREEN
          }
      }
      @end

      El uso de la presentación de la bandera para establecer la dirección en la que desea animar o que alguna vez la condición de que usted prefiera. Aquí está el enlace a Apple de referencia.

    • Gran. Una cosa, no se necesita presentar variable. UINavigationControllerOperation indica que esta operación es Push o Pop.
  5. 2

    Gracias chicos por los comentarios. Encontrado una solución completamente recrear la UINavigationController del comportamiento. Cuando estaba casi terminado, me encontré con Nick Lockwood la solución:

    https://github.com/nicklockwood/OSNavigationController

    OSNavigationController es una fuente abierta de re-implementación de UINavigationController. Actualmente cuenta con sólo un subconjunto de la funcionalidad de UINavigationController, pero el objetivo a largo plazo es replicar el 100% de las características.

    OSNavigationController no está realmente destinado a ser utilizado como-es. La idea es que usted puede hacer un fork y, a continuación, personalizar fácilmente su apariencia y comportamiento para adaptarse a cualquier requisito especial que su aplicación puede tener. Personalización de OSNavigationController es mucho más sencillo que intentar personalizar UINavigationController debido al hecho de que el código está abierto y usted no necesita preocuparse acerca de los métodos privados, indocumentados comportamiento, o la implementación de los cambios entre versiones.

    Reemplazando mi UINavigationController con su código, yo era capaz de trabajar con imágenes de fondo en UINavigationcontrollers

    Gracias!

  6. 2

    Simplemente agregar en:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

    Este:

    [[self window] setBackgroundColor:[UIColor whiteColor]];

    El resultado final:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions (NSDictionary *)launchOptions {    
        [[self window] setBackgroundColor:[UIColor whiteColor]];
    
        //Override point for customization after application launch.
        return YES;
    }
    • Guarda mi tiempo, gracias @Riko87
  7. 1

    Al parecer en iOS7 hay una nueva manera de definir sus propios UIViewController transiciones. Busque en el google docs para UIViewControllerTransitioningDelegate. Además, aquí hay un enlace a un artículo sobre esto: http://www.doubleencore.com/2013/09/ios-7-custom-transitions/

    • gracias! Se verá en ella
    • A menos que me equivoque, esto parece para trabajar sólo con la presentación de un controlador de vista. No pude hacer que funcione al empujar un controlador de vista de un controlador de navegación.
  8. 0

    He votado a favor de @Arne de la respuesta, porque me parece la solución más elegante a este problema. Me gustaría añadir algo de código con el fin de responder a @proyecto de Ley del problema a partir de sus comentarios en @Arne de la solución. Aquí el comentario de cita:

    Gracias, esto funciona para mí. Sin embargo, cuando el usuario toca la Espalda
    botón, vuelve a la busted animación (debido a que el botón atrás
    no llame popViewControllerRetro). – Proyecto de ley de 3 de Oct a las 12:36

    Con el fin de llamar popViewControllerRetro cuando se pulsa el botón, hay un pequeño hack que puede realizar con el fin de lograr esto. Vaya a su empujado controlador de vista de la importación de UIViewController+Retro.h y añadir este código en tu viewWillDisappear método:

    - (void)viewWillDisappear:(BOOL)animated {
        if ([self.navigationController.viewControllers indexOfObject:self] == NSNotFound) {
            [self.navigationController popViewControllerRetro];
        }
    
        [super viewWillDisappear:animated];
    }

    Esta declaración si se detectan cuando se presiona el botón y llamar popViewControllerRetro a partir de la categoría de clase.

    Saludos.

Dejar respuesta

Please enter your comment!
Please enter your name here