iOS 转场动画笔记

来源:互联网 发布:淘宝网折叠床单人 编辑:程序博客网 时间:2024/06/06 21:44

文章转载出自:http://www.kittenyang.com/magicmove/

详细实现步骤在原文有说明

简单的说:导航的转场动画主要的实现原理步骤

1.创建2个动画过度Animated Transition对象(push一个效果+pop一个效果)NSObject实现UIViewControllerAnimatedTransitioning协议 主要重写2个协议方法

    a.- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext//动画时间

    b.- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext//两个页面的动画效果处理

2.VC里面实现UINavigationControllerDelegate代理重写1个协议方法

   a.- (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController

                                   animationControllerForOperation:(UINavigationControllerOperation)operation

                                                fromViewController:(UIViewController *)fromVC

                                                  toViewController:(UIViewController *)toVC


先看效果

1.构建过度动画

转场动画的自定义的精髓在于动画过度对象 - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext协议里面 可以获取到FromVC 和 ToVC 然后再在VC暴露属性出来做相应的alpha frame 等动画  之前要创建2个过渡动画对象 

一个是push

MagicMoveTransition

一个是pop

MagicMoveInverseTransition

原理都是一样 只是动画要自定义 有区别


例子:

////  MagicMoveTransition.m//  KYMagicMove////  Created by Kitten Yang on 1/17/15.//  Copyright (c) 2015 Kitten Yang. All rights reserved.//#import "MagicMoveTransition.h"#import "FirstCollectionViewController.h"#import "SecondViewController.h"#import "CollectionViewCell.h"#import "UIView+MotionBlur.h"@implementation MagicMoveTransition- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext{    return 0.25f;}- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{    //获取两个VC 和 动画发生的容器    FirstCollectionViewController *fromVC = (FirstCollectionViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];    SecondViewController *toVC   = (SecondViewController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];    UIView *containerView = [transitionContext containerView];            //对Cell上的 imageView 截图,同时将这个 imageView 本身隐藏    CollectionViewCell *cell =(CollectionViewCell *)[fromVC.collectionView cellForItemAtIndexPath:[[fromVC.collectionView indexPathsForSelectedItems] firstObject]];    UIView * snapShotView = [cell.imageView snapshotViewAfterScreenUpdates:NO];    snapShotView.frame = fromVC.finalCellRect = [containerView convertRect:cell.imageView.frame fromView:cell.imageView.superview];    cell.imageView.hidden = YES;        //设置第二个控制器的位置、透明度    toVC.view.frame = [transitionContext finalFrameForViewController:toVC];    toVC.view.alpha = 0;    toVC.imageViewForSecond.hidden = YES;        //把动画前后的两个ViewController加到容器中,顺序很重要,snapShotView在上方    [containerView addSubview:toVC.view];    [containerView addSubview:snapShotView];        //动起来。第二个控制器的透明度0~1;让截图SnapShotView的位置更新到最新;    [containerView layoutIfNeeded];    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{//        [containerView layoutIfNeeded];        toVC.view.alpha = 1.0;        snapShotView.frame = [containerView convertRect:toVC.imageViewForSecond.frame fromView:toVC.view];    } completion:^(BOOL finished) {        //为了让回来的时候,cell上的图片显示,必须要让cell上的图片显示出来        toVC.imageViewForSecond.hidden = NO;        cell.imageView.hidden = NO;        [snapShotView removeFromSuperview];        //告诉系统动画结束        [transitionContext completeTransition:!transitionContext.transitionWasCancelled];    }];}@end

之后的动画可以自己定义做更优美的动画 以上是我稍微修改了原文作者kitten-yang的源码

2.使用:

FromVC里面的在viewDidAppear设置self.navigationController.delegate =self;(否则pop回来第二次push触发不到协议) 然后实现协议方法

 

#pragma mark <UINavigationControllerDelegate>- (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController                                   animationControllerForOperation:(UINavigationControllerOperation)operation                                                fromViewController:(UIViewController *)fromVC                                                  toViewController:(UIViewController *)toVC{    if ([toVC isKindOfClass:[SecondViewController class]])    {        MagicMoveTransition *transition = [[MagicMoveTransition alloc]init];        return transition;    }    else    {        return nil;    }}
ToVC里面也需要设置self.navigationController.delegate = self但是不要像FromVC一样在viewDidAppear

#pragma mark <UINavigationControllerDelegate>- (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController                                   animationControllerForOperation:(UINavigationControllerOperation)operation                                                fromViewController:(UIViewController *)fromVC                                                  toViewController:(UIViewController *)toVC{    if ([toVC isKindOfClass:[FirstCollectionViewController class]])    {        MagicMoveInverseTransition *inverseTransition = [[MagicMoveInverseTransition alloc]init];        return inverseTransition;    }    else    {        return nil;    }}

源码地址:https://github.com/Jacky-LinPeng/MegicMove   

特别说明一下: 以上的源码是我修改kitten-yang的源码 主要的代码还是kitten-yang的成果 因为很喜欢这个效果 所以写这个笔记 备忘



0 0
原创粉丝点击