注释:纸上得来终觉浅,绝知此事要躬行。好吧,我只是代码的搬运工,照抄大神的代码,自己再重写一遍。原文:http://kittenyang.com/magicmove/
效果:
总体上实现了自定义导航控制器的跳转。类似照片放大缩小的效果。
1.自定义实现动画的类,实现UIViewControllerAnimatedTransitioning代理
2.控制器实现UINavigationControllerDelegate代理,返回自定义类。
第一次写,为了理解方便,push和pop动画分开写了。写了2个类,里面代码都类似。如果深究的话 ,应该可以写一个类,在里面判断就行了。
动画逻辑都在自定义类里。实现了2个代理方法。
#import "PushAnimator.h"
#import "ViewController.h"
#import "SecondVC.h"
@implementation PushAnimator
//动画时间
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
return 0.6;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
// 动画容器中关联的2个控制器 通过viewControllerForKey获得
ViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
SecondVC *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *containerView = transitionContext.containerView;
// 对需要显示的view进行截屏
UIView *snapView = [fromVC.IMGView snapshotViewAfterScreenUpdates:NO];
// 坐标转化,把图片原来的坐标转到containerView上
CGRect frame = [containerView convertRect:fromVC.IMGView.frame fromView:fromVC.view];
snapView.frame = frame;
// 隐藏原来图片,否则图片移动的时候还能看到原图
fromVC.IMGView.hidden = YES;
// 给需要显示的控制器的view的坐标赋值,并隐藏需要显示的图片
toVC.view.frame = [transitionContext finalFrameForViewController:toVC];
toVC.view.alpha = 0;
toVC.IMGView.hidden = YES;
// 先后添加需要显示的控制器的view和截图到动画控制器上。顺序不能错。
[containerView addSubview:toVC.view];
[containerView addSubview:snapView];
// 简单动画,更改透明度和frame
[UIView animateWithDuration:0.6 animations:^{
toVC.view.alpha = 1;
snapView.frame = [toVC.view convertRect:toVC.IMGView.frame toView:containerView];
} completion:^(BOOL finished) {
fromVC.IMGView.hidden = NO;
toVC.IMGView.hidden = NO;
// 必须实现这个方法,告诉系统动画结束或者被打断了
[transitionContext completeTransition:!transitionContext.transitionWasCancelled];
[snapView removeFromSuperview];
}];
}
上面是push动画,pop代码几乎一样。应该可以合并。
后续把返回手势加上。