Controller 转换

UINavigationControllerDelegate中相关方法


- (id)

     navigationController:(UINavigationController *)navigationController

     animationControllerForOperation:(UINavigationControllerOperation)operation

     fromViewController:(UIViewController*)fromVC

     toViewController:(UIViewController*)toVC

{

     if (operation == UINavigationControllerOperationPush) {

     //可以给每个转场创建新的animator对象,或者共用同一个animator     

     return self.animator;

     }

     return nil;

}

创建一个自定义的动画类

示例代码下载地址:https://github.com/objcio/issue5-view-controller-transitions


//实现这个协议

@interface Animator : NSObject 

@end

//动画持续时间

- (NSTimeInterval)transitionDuration:(id )transitionContext

{

     return 0.25;

}

//动画执行效果

- (void)animateTransition:(id)transitionContext

{

     UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

     UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

     [[transitionContext containerView] addSubview:toViewController.view];

     toViewController.view.alpha = 0;

     [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{

          fromViewController.view.transform = CGAffineTransformMakeScale(0.1, 0.1);

          toViewController.view.alpha = 1;

     } completion:^(BOOL finished) {

          fromViewController.view.transform = CGAffineTransformIdentity;

          [transitionContext completeTransition:![transitionContext transitionWasCancelled]];

     }];

}

//实现交互式转场动画,只需要覆盖另一个UINavigationControllerDelegate的方法

- (id )navigationController:(UINavigationController*)navigationController

     interactionControllerForAnimationController:(id )animationController

{

     //返回的是UIPercentDrivenInteractionTransition类的一个实例 

     return self.interactionController;

}

//创建一个拖动手势Pan Rcognizer

if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) {

    //当用户从屏幕右半部分开始触摸时,把下次动画效果设置为交互式

     if (location.x > CGRectGetMidX(view.bounds)) {

          navigationControllerDelegate.interactionController = [[UIPercentDrivenInteractiveTransition alloc] init];

     [self performSegueWithIdentifier:PushSegueIdentifier sender:self];

     }

} else if (panGestureRecognizer.state == UIGestureRecognizerStateChanged) {

    //根据用户手指拖动的距离计算一个百分比,切换的动画效果也跟这个百分比走。

     CGFloat d = (translation.x / CGRectGetWidth(view.bounds)) * -1;

     [interactionController updateInteractiveTransition:d];

} else if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) {

     //根据用户手势的停止状态来判断该操作是结束还是取消

     if ([panGestureRecognizer velocityInView:view].x < 0) {

          [interactionController finishInteractiveTransition];

     } else {

          [interactionController cancelInteractiveTransition];

     }

     navigationControllerDelegate.interactionController = nil;

}

用GPUImage做转场动画

示例代码地址:https://github.com/FangYiXiong/ViewControllerTransitionsDemo/tree/master/issue5-demo2%EF%BC%88GPUImage%EF%BC%89
实现的效果是两个view controller像素化,然后相互消融在一起。
先创建一个自定义类,实现UIViewControllerAnimatedTransitioning 和 UIViewControllerInteractiveTransitioning两个协议。将图片一次性加载到GPU中。直接用OpenGL画图使用GPUImage封装好的接口。


@interface GPUImageAnimator : NSObject

     

@property (nonatomic) BOOL interactive;

@property (nonatomic) CGFloat progress;

- (void)finishInteractiveTransition;

- (void)cancelInteractiveTransition;

@end

创建滤镜链filter chain也很直观。GPUImage没有提供动画效果,可以使用CADisplayLink完成渲染一帧就更新下一滤镜的动态滤镜效果。


self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(frame:)];

[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];

//在frame方法中,可以根据时间来更新动画,相应的更新滤镜:

- (void)frame:(CADisplayLink*)link

{

     self.progress = MAX(0, MIN((link.timestamp - self.startTime) / duration, 1));

     self.blend.mix = self.progress;

     self.sourcePixellateFilter.fractionalWidthOfAPixel = self.progress *0.1;

     self.targetPixellateFilter.fractionalWidthOfAPixel = (1- self.progress)*0.1;

     [self triggerRenderOfNextFrame];

}

GPUImage开源库地址:https://github.com/BradLarson/GPUImage

你可能感兴趣的:(Controller 转换)