深入学习iOS7自定义导航转场动画

2020-01-14 20:05:04刘景俊

1. 实现startInteractiveTransition:方法,用于初始化专场动画。
2. 获取transitionContext 对象的引用(如果继承了UIPercentDrivenInteractiveTransition,可以看到它自动帮我们完成了这一步骤,因此这里我们必须手动获取该对象)。
3. 和之前一样,在适当的情况下调用updateInteractiveTransition:,cancelInteractiveTransition和finishInteractiveTransition(对于导航控制器来说,完成方法中还需要显示或隐藏导航栏)。
4. 完成后仍然请记住调用transitionCompleted:。

下面是我通过自定义的交互控制器来实现与之前相同的动画,仍然是使用捏合手势控制转场动画。


 -(void)startInteractiveTransition: 
(id)transitionContext { 
//获取transitionContext对象的引用 
_context = transitionContext; 
//获取容器视图引用 
UIView *containerView = [transitionContext 
containerView]; 
UIViewController *fromViewController = [transitionContext 
viewControllerForKey:UITransitionContextFromViewControllerKey 
]; 
UIViewController *toViewController = [transitionContext 
viewControllerForKey:UITransitionContextToViewControllerKey]; 
//插入“to”视图 
toViewController.view.frame = [transitionContext 
finalFrameForViewController:toViewController]; 
[containerView insertSubview:toViewController.view 
belowSubview:fromViewController.view]; 
//保留需要缩?小的视图的引用 
_transitioningView = fromViewController.view; 
} 
-(void)updateWithPercent:(CGFloat)percent { 
CGFloat scale = fabsf(percent-1.0); 
_transitioningView.transform = 
CGAffineTransformMakeScale(scale, scale); 
[_context updateInteractiveTransition:percent]; 
} 
-(void)end:(BOOL)cancelled { 
if (cancelled) { 
[UIView animateWithDuration:_completionSpeed 
animations:^{ 
_transitioningView.transform = 
CGAffineTransformMakeScale(1.0, 1.0); 
} completion:^(BOOL finished) { 
[_context cancelInteractiveTransition]; 
[_context completeTransition:NO]; 
}]; 
} else { 
[UIView animateWithDuration:_completionSpeed 
animations:^{ 
_transitioningView.transform = 
CGAffineTransformMakeScale(0.0, 0.0); 
} completion:^(BOOL finished) { 
[_context finishInteractiveTransition]; 
[_context completeTransition:YES]; 
}]; 
} 
} 

你可以让动画控制器同时实现UIViewControllerInteractive-Transitioning和 UIViewControllerAnimatedTransitioning(像示例程序中那样),从而把所有代码都放在一个类中。你也可以将交互控制器和动画控制器分成两个类——协议这一语法特性的妙处在于,你可以轻松实现符合需求的最佳解决方案。

更多小技巧
在block中选择是否进行动画
开发者或许会遇到这样一种情况:在一串精美的动画效果中,我们需要让某些视图不进行动画,从而营造一种动静相宜的效果。在动画block方法推出之前,我们可以在[UIView beginAnimations]和[UIView commitAnimations]之间使用setAnimationsEnabled方法来设置哪些动画不需要执行。而在iOS7SDK中,苹果公司为开发者提供了新方法,只要把不需要执行的动画写在block中即可: