UIViewController转场动画基础用法-modal篇

转场,从一个场景转换到另一个场景。

UIViewController转场动画基础用法-modal篇_第1张图片
TransitioningAnimationDemo1.gif

modal动画

通过- (void)presentViewController:animated:completion:方法跳转到另一个页面时,可以自定义modal动画。

从代码的角度看,启用动画的入口是这样的:

vc.transitioningDelegate = self;
[self presentViewController:vc animated:YES completion:nil];

给vc的transitioningDelegate属性赋值,为即将跳转的vc指定转场动画代理。简单起见,在这里,当前controller自己充当了代理。而作为代理需要实现协议。

@interface ViewController () 

协议中有两个基础方法,分别要求代理返回present时的动画以及dismiss时的动画。

- (nullable id )animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source;
- (nullable id )animationControllerForDismissedController:(UIViewController *)dismissed;

剩下的事情,就需要代理去考虑怎么搞出两个实现了协议的动画对象来。

我们可以写一个类专门来实现动画协议,作为动画的实现类。然后代理就可以轻松搞出两个动画对象,实现转场代理协议。

@interface PictureBroswerTransitionAnimator : NSObject 

动画协议中,有两个必须实现的方法:

/// 返回动画持续时间
- (NSTimeInterval)transitionDuration:(nullable id )transitionContext;
/// 动画实现过程
- (void)animateTransition:(id )transitionContext;

可以看到,其中的关键方法就是-(void)animateTransition:,系统会向此方法传入一个参数transitionContext,它代表了整个转场环境,包含了转场过程中的关键信息,比如从哪里转到哪里。

实现动画的关键方法
- (void)animateTransition:(id)transitionContext

获取转场过程的三个视图:containerView、fromView、toView。
containerView是动画过程中提供的暂时容器。
fromView是转场开始页的视图。
toView是转场结束页的视图。

UIView *fromView;
UIView *toView;
if ([transitionContext respondsToSelector:@selector(viewForKey:)]) {
    // iOS8以上用此方法准确获取
    fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
    toView = [transitionContext viewForKey:UITransitionContextToViewKey];
}
else {
    fromView = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view;
    toView = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view;
}
UIView *container = [transitionContext containerView];

转场的过程,大多数情况下我们都是对toView作各种变换操作,例如改变toView的alpha,size,旋转等等。 在对它进行操作前,需要先把它放到container上才能显示出来。
[container addSubview:toView];

最后需要我们自己弄出个动画来~囧

pictureView.transform = startTransform;
pictureView.center = startCenter;
[UIView animateWithDuration:self.duration animations:^{
    pictureView.transform = endTransform;
    pictureView.center = endCenter;
} completion:^(BOOL finished) {
    BOOL wasCancelled = [transitionContext transitionWasCancelled];
    [transitionContext completeTransition:!wasCancelled];
}];

这里注意一下,在我们自己写的动画完结时,一定要告诉所在的转场环境对象transitionContext,我们的动画完成了,它才会进行动画结束后的收尾工作:

[transitionContext completeTransition:YES];

在转场的过程中,动画有可能被各种原因打断,通过transitionWasCancelled方法可以知道是否被打断:

BOOL wasCancelled = [transitionContext transitionWasCancelled];
[transitionContext completeTransition:!wasCancelled];

项目源码
下载地址

你可能感兴趣的:(UIViewController转场动画基础用法-modal篇)