注釋:紙上得來終覺淺,絕知此事要躬行。好吧,我只是代碼的搬運工,照抄大神的代碼,自己再重寫一遍。原文:http://kittenyang.com/magicmove/
10D1E51742B8F67DB41F7928B98392AD.gif
效果:
AAA.gif
總體上實現了自定義導航控制器的跳轉。類似照片放大縮小的效果。
1.自定義實現動畫的類,實現UIViewControllerAnimatedTransitioning代理
2.控制器實現UINavigationControllerDelegate代理,返回自定義類。
qwetdf.png
第一次寫,為了理解方便,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代碼幾乎一樣。應該可以合并。
后續把返回手勢加上。