在iOS7以前,开发者如果希望定制导航控制器推入推出视图时的转场动画,一般都只能通过子类化UINavigationController或者自己编写动画代码去覆盖相应的方法,现在iOS7为开发者带来了福音,苹果公司引入了大量新API,给予了开发者很高的自由度,在处理由UIViewController管理的UIView动画时,这些API使用方便,可扩展性也很强,定制起来非常轻松:
- 全新的针对UIView的动画block方法
- 全新的UIViewControllerAnimatedTransitioning协议以及动画控制器的概念
- Interaction Controllers以及Transition Coordinators
-
全新的针对动画的助手API(简便方法)
全新的针对UIView的动画block方法
iOS4的发布带来了强大的block方法,在编写UIView动画时使用block可以轻松地得到满意的效果,然而有些情况下,我们还是不得不直接使用Core Animation。幸运的是,苹果公司在iOS7中增加了2个新的基于block的方法,这样我们就很少再需要直接使用Core Animation了。
1、关键帧动画
iOS7为UIView封装了一组API,让我们很容易的得到与Core Animation框架中的CAKeyframeAnimation一样的效果。[UIView animateKeyframesWithDuration:duration delay:delay options:options animations:^{ [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{ //第一帧要执行的动画 }]; [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.5 animations:^{ //第二帧要执行的动画 }]; } completion:^(BOOL finished) { //动画结束后执行的代码块 }];新引入的animateKeyframesWithDuration与CAKeyframeAnimation的关系,可以比对animateWithDuration和CABasicAnimation,我们只需要将每一帧动画加入到block方法中,并传入此段动画在全过程中的相对开始时间和执行时间(duration具体是指此段动画的执行时间占全过程的百分比)。同时,你可以在一次动画中使用多个关键帧,只需使用addKeyframe依次将所有关键帧加入动画执行栈中。
下面是一个简单的例子:在示例应用中,我使用关键帧block来退出模态视图控制器。
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.15 animations:^{ //顺时针旋转90度 snapshot.transform = CGAffineTransformMakeRotation(M_PI * -1.5); }]; [UIView addKeyframeWithRelativeStartTime:0.15 relativeDuration:0.10 animations:^{ //180度 snapshot.transform = CGAffineTransformMakeRotation(M_PI * 1.0); }]; [UIView addKeyframeWithRelativeStartTime:0.25 relativeDuration:0.20 animations:^{ //摆过中点,225度 snapshot.transform = CGAffineTransformMakeRotation(M_PI * 1.3); }]; [UIView addKeyframeWithRelativeStartTime:0.45 relativeDuration:0.20 animations:^{ //再摆回来,140度 snapshot.transform = CGAffineTransformMakeRotation(M_PI * 0.8); }]; [UIView addKeyframeWithRelativeStartTime:0.65 relativeDuration:0.35 animations:^{ //旋转后掉落 //最后一步,视图淡出并消失 CGAffineTransform shift = CGAffineTransformMakeTranslation(180.0, 0.0); CGAffineTransform rotate = CGAffineTransformMakeRotation(M_PI * 0.3); snapshot.transform = CGAffineTransformConcat(shift, rotate); _coverView.alpha = 0.0; }];










