这是自定义转场系列的第四篇。由于具有一定的连续性,我会忽略一些基础,所以如果你是第一次看这个系列,可以先过目之前的几篇 ——— UIViewControllerTransitioning的用法 、实现Keynote中的神奇移动效果、实现通过圆圈放大缩小的转场动画。
老规矩,先端上GIF。
How to work
首先在StoryBoard上拖两个UIViewController。并且在第一个VC上放一个button,使用Action Segue连接到第二个VC。
然后回到代码界面。和以往一样,我们需要创建两个文件:一个用于从第一个VC过渡到第二个VC的动画(如push),另一个这是第二个过渡到第一个VC的动画(如pop)。这里不得不说iOS7中引入的这种解耦合的方式,它的意义在于无论在哪儿需要用到转场动画的地方,直接把这两个文件扔过去就行了。
我们创建两个文件:KYPushTransition 和 KYPopTransition 。从名字可以看出,后一个是前一个的反转动画。其实,我们完全可以把两个文件写在一起:KYTransition 。因为两个文件的代码结构几乎别无二致,不同的地方也只要用布尔值区分一下就行了。但这里为了让介绍思路清晰,我们把两个动画分开来实现。
首先是KYPushTransition。
先继承 UIViewControllerAnimatedTransitioning 协议。实现下面两个方法:
- (NSTimeInterval)transitionDuration:(id )transitionContext{
//动画的时间
return 0.6f;
}
- (void)animateTransition:(id )transitionContext{
//动画的逻辑
...
}
下面具体介绍动画的逻辑。
- (void)animateTransition:(id )transitionContext{
//1
FirstViewController *fromVC = (FirstViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
SecondViewController *toVC = (SecondViewController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *fromView = fromVC.view;
UIView *toView = toVC.view;
UIView *containerView = [transitionContext containerView];
[containerView addSubview:toView];
[containerView sendSubviewToBack:toView];
//2
CATransform3D transform = CATransform3DIdentity;
transform.m34 = -0.002;
containerView.layer.sublayerTransform = transform;
//3
CGRect initialFrame = [transitionContext initialFrameForViewController:fromVC];
fromView.frame = initialFrame;
toView.frame = initialFrame;
//4
[self updateAnchorPointAndOffset:CGPointMake(0.0, 0.5) view:fromView];
//5
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = fromView.bounds;
gradient.colors = @[(id)[UIColor colorWithWhite:0.0 alpha:0.5].CGColor,
(id