ios - online - iphone xs
¿Cómo empezaría a replicar la transición del controlador de vista personalizada que Apple usa como predeterminado en iOS 7? (3)
Usando las transiciones del controlador de vista personalizado de iOS 7, quiero lograr un efecto visual similar al de la transición del controlador de vista predeterminado de Apple en iOS 7.
(La que puede deslizar para sacar un controlador de vista de la pila deslizándolo de izquierda a derecha, donde el controlador de vista superior se desliza de la parte superior del otro con una sombra y la barra de navegación cambia).
Sin embargo, estoy teniendo muchas dificultades para implementar esto. La mayoría de los tutoriales sobre controladores de vista personalizados tienen efectos muy diferentes a los predeterminados para mostrar de qué está habilitado el API, pero quiero replicar este.
En mi subclase para implementar <UIViewControllerAnimatedTransitioning>
tengo el siguiente código para la animación interactiva:
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
[transitionContext.containerView addSubview:toViewController.view];
[transitionContext.containerView addSubview:fromViewController.view];
fromViewController.view.layer.shadowOffset = CGSizeMake(0.0, 0.0);
fromViewController.view.layer.shadowColor = [UIColor blackColor].CGColor;
fromViewController.view.layer.shadowRadius = 5.0;
fromViewController.view.layer.shadowOpacity = 0.5;
[UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
CGRect newFrame = fromViewController.view.frame;
newFrame.origin.x = CGRectGetWidth(fromViewController.view.bounds);
fromViewController.view.frame = newFrame;
} completion:^(BOOL finished) {
[transitionContext completeTransition:!transitionContext.transitionWasCancelled];
}];
}
Sin embargo, el código de la sombra hace que se demore enormemente (incluso si uso los nuevos métodos de snapshot
) y no puedo averiguar cómo manipular la barra de navegación .
¿Alguien ha intentado hacer algo similar a esto y puede proporcionar un código de muestra?
Proyecto de muestra para pruebas si desea: http://cl.ly/0B3q1b390x0D
Crédito a objc.io por el código base.
Creo el efecto utilizando Dynamics. Creo mi propia subclase ViewController con los siguientes métodos.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil forMultipleDirections:(BOOL)isTwoDirections;
- (void)addVelocityForGesture:(UIPanGestureRecognizer *)recognizer;
- (UIDynamicItemBehavior*) itemBehaviourForView;
Luego agregué física y un reconocedor de gestos para manejar el gesto de panoramización. para hacer que se vea en la parte superior solo agrega una sombra de desplazamiento.
_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.parentViewController.view];
_gravity = [[UIGravityBehavior alloc] init];
_gravity.gravityDirection = CGVectorMake(-1.5, 0);
[_animator addBehavior:_gravity];
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.view]];
[collision addBoundaryWithIdentifier:@1 fromPoint:CGPointMake(0, 0) toPoint:CGPointMake(0, self.parentViewController.view.frame.size.height)];
[_animator addBehavior:collision];
[_gravity addItem:self.view];
UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[self.view]];
[itemBehavior setElasticity:0.2];
[_animator addBehavior:itemBehavior];
Necesitará más métodos para agregar velocidad de acuerdo con la dirección de la panorámica, luego necesitará encontrar un punto en el que desee descartar u ocultar el ChildViewController dependiendo de su caso de uso, etc ... Lo hice y funciona bien bien para mí, ya que está utilizando Dynamics, solo es compatible con iOS7 +
Eche un vistazo a ECSlidingViewController Lo he usado un par de veces. Si entiende cómo funciona, puede implementar fácilmente algo similar.
Si quieres reinventar la rueda, mi respuesta es inútil, lo siento.
La configuración de shadowPath
aumenta considerablemente el rendimiento de esta sombra.
Simplemente agregue esto en su método animateTransition:
después de haber establecido las propiedades de la sombra. Esto evita el costoso renderizado fuera de la pantalla que normalmente causa la sombra.
[fromViewController.view.layer setShadowPath:[[UIBezierPath bezierPathWithRect:fromViewController.view.bounds] CGPath]];
Descargué tu proyecto de muestra y lo hice, el tartamudeo ahora se ha ido por completo.
Un poco de información sobre lo que hace esto here .
EDITAR:
La respuesta acerca de cómo manipular la barra de navegación es que parece que no puedes. Para hacerlo, deberá volver a implementar su propia clase de tipo NavigationController desde cero. La animación de transición para la barra de navegación se realiza internamente mediante el controlador de vista de contenedor (el controlador UINavigationController
) y no aparece en ninguna parte del código.