iOS-自定义交互式转场动画

自定义转场动画主要有以下步骤

  • 自定义导航栏
  • 自定义交互动画
  • 通过UIPercentDrivenInteractiveTransition协议实现交互
自定义导航栏 自定义导航栏需要遵守协议,该协议主要有两个协议方法:
// 该方法返回导航跳转时的动画,如果返回nil,则是系统默认的跳转动画,并且通过operation来判断当前执行push还是pop -(id)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC { return nil; }

// 该方法返回自定义交互动画,只有实现该协议,才能在跳转时实现与用户交互 -(id)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id)animationController { return nil; }

自定义跳转动画 自定义跳转动画需要遵守协议,该协议主要实现下面的方法:
// 该方法返回动画执行的时间,transitionContext由系统获取 -(NSTimeInterval)transitionDuration:(id)transitionContext { return 0.3; }

// 通过该协议,获取跳转的两个VC -(void)animateTransition:(id)transitionContext { UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; [self animateTransition:transitionContext fromVC:fromVC toVC:toVC fromView:fromVC.view toView:toVC.view]; }

// 这是模仿系统导航跳转的例子 - (void)animateTransition:(id)transitionContext fromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC fromView:(UIView *)fromView toView:(UIView *)toView{ [[transitionContext containerView] addSubview:toView]; if (_isPush) { [[transitionContext containerView] bringSubviewToFront:toView]; toView.transform = CGAffineTransformMakeTranslation(-toView.bounds.size.width, 0); } else{ [[transitionContext containerView] bringSubviewToFront:fromView]; } [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ if (_isPush) { toView.transform = CGAffineTransformIdentity; } else{ fromView.transform = CGAffineTransformMakeTranslation(-fromView.bounds.size.width, 0); } } completion:^(BOOL finished) { transitionContext completeTransition:![transitionContext transitionWasCancelled]]; }]; }

实现交互 【iOS-自定义交互式转场动画】自定义一个类,继承自UIPercentDrivenInteractiveTransition,它遵守协议,我们可以告诉它当前转场动画进行的百分比,它再来更新动画的进度。转场动画进行的百分比可以通过手势来计算
// 在view上加入pan手势 UIPanGestureRecognizer *gesture = objc_getAssociatedObject(self.interactiveVC.view, (__bridge const void *)(kpanGestureKey)); if (gesture) { [self.interactiveVC.view removeGestureRecognizer:gesture]; } gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)]; [self.interactiveVC.view addGestureRecognizer:gesture]; objc_setAssociatedObject(self.interactiveVC.view, (__bridge const void *)(kpanGestureKey), gesture,OBJC_ASSOCIATION_RETAIN_NONATOMIC);

// 当pan手势移动,通过移动的距离来计算当前跳转动画需要完成的百分比,当手势结束时,判断动画完成的百分比。如果>50%,finishInteractiveTransition完成跳转动画;如果<50%,cancelInteractiveTransition取消动画,返回原样 case UIGestureRecognizerStateChanged: CGFloat fraction = point.x / [[UIScreen mainScreen] bounds].size.width; fraction = fminf(fmaxf(fraction, 0.0), 1.0); self.shouldComplete = (fraction > 0.5); [self updateInteractiveTransition:fraction]; break; case UIGestureRecognizerStateEnded: case UIGestureRecognizerStateCancelled: self.interactioning = NO; if (!self.shouldComplete || pan.state == UIGestureRecognizerStateCancelled) { [self cancelInteractiveTransition]; } else { [self finishInteractiveTransition]; } break;

最后附上Demo的地址https://github.com/cdcyd/CommonControlsCollection

    推荐阅读