首先上效果图
平时做动画,用于view之间,用[UIView animateKeyframesWithDuration:<#(NSTimeInterval)#> delay:<#(NSTimeInterval)#> options:<#(UIViewKeyframeAnimationOptions)#> animations:<#^(void)animations#> completion:<#^(BOOL finished)completion#>]简单,方便。但是想要实现视图控制器之间的过渡动画,感觉就不是如此的方便了。想想平时最常用的视图之间转换的方法[self.navigationController pushViewController:<#(nonnull UIViewController *)#> animated:<#(BOOL)#>],然后,后续的工作,就是系统帮我们完成了。
想要自定义转场动画,我们需要实现navigationController的一个代理方法
此代理方法需要返回一个服从UIViewControllerInteractiveTransitioning协议的对象,此协议有3个代理方法
第一个代理方法用来设置动画时长,第二个代理方法就是实现动画的核心代码了。首先,就是需要获取2个控制器的view了,但是代理方法里就一个参数transitionContext,类型为id类型,服从UIViewControllerContextTransitioning协议。重要的方法有3个
1 - (nullableUIView*)containerView;(容器视图)
2 - (nullable__kindofUIViewController*)viewControllerForKey:(NSString*)key; (用来获取转场的视图)
3 - (void)completeTransition:(BOOL)didComplete; (转场动画完成时,务必调用)
下面上代码:
UIViewController*fromVC = [transition ContextviewControllerForKey:UITransitionContextFromViewControllerKey];// 当前视图
UIViewController*toVC = [transition ContextviewControllerForKey:UITransitionContextToViewControllerKey];//push的视图
UIView*containView = [transition ContextcontainerView];//视图容器
if(self.type==Push) {//当前转场类型,push
[containViewaddSubview:toVC.view];
[containViewaddSubview:fromVC.view];
[selfupdateAnchorPointAndOffset:CGPointMake(0.5,1)view:fromVC.view];//改变视图锚点,锚点可以理解为做动画时的围绕点(默认0.5 0.5 围绕中心点做动画)
后面代码想必用过动画的都懂,就不一一解释了
[UIViewanimateKeyframesWithDuration:3.0delay:0options:0animations:^{
[UIViewaddKeyframeWithRelativeStartTime:0.0relativeDuration:0.65animations:^{
fromVC.view.transform=CGAffineTransformMakeRotation(M_PI_2);
}];
[UIViewaddKeyframeWithRelativeStartTime:0.65relativeDuration:1.00animations:^{
fromVC.view.transform=CGAffineTransformMakeRotation(M_PI_2*2);
}];
}completion:^(BOOLfinished) {
[fromVC.viewremoveFromSuperview];
[transitionContextcompleteTransition:YES];//动画介绍时调用
}];
}else{
[containViewaddSubview:toVC.view];
UIView*snapshot = [fromVC.viewsnapshotViewAfterScreenUpdates:NO];
snapshot.frame= fromVC.view.frame;
[containViewaddSubview:snapshot];
[containViewbringSubviewToFront:snapshot];
[fromVC.viewremoveFromSuperview];
[containViewinsertSubview:snapshotbelowSubview:toVC.view];
[UIViewanimateKeyframesWithDuration:3.0delay:0options:0animations:^{
[UIViewaddKeyframeWithRelativeStartTime:0.0relativeDuration:0.65animations:^{
toVC.view.transform=CGAffineTransformRotate(toVC.view.transform,M_PI_2);
}];
[UIViewaddKeyframeWithRelativeStartTime:0.65relativeDuration:1.00animations:^{
toVC.view.transform=CGAffineTransformRotate(toVC.view.transform,M_PI_2);
}];
}completion:^(BOOLfinished) {
[snapshotremoveFromSuperview];
[transitionContextcompleteTransition:YES];
}];
}
demo下载地址:https://github.com/xuefeime/TransAnimatonTest