transition转场动画

    最近在学习苹果的transition转场动画,写一篇文章来记录一下实现转场动画的基本步骤。

    iOS7以后,苹果为视图跳转单独提供了一整套的动画处理。原理我就不说了,网上一搜一大堆的,我主要说一下实现转场动画的具体步骤。

    一、TestViewController.m

    1、在跳转控制器中遵守<UIViewControllerTransitioningDelegate,UINavigationControllerDelegate>协议

    2、实现<UIViewControllerTransitioningDelegate,UINavigationControllerDelegate>的协议方法,在其中返回一个遵守<UIViewControllerAnimatedTransitioning>协议的对象,在此对象中实现所需要的transition转场动画

    3、跳转到toViewController,可用storyboard跳转,segue可以是modal或者push

    4、设置toViewController的transitioningDelegate = TestViewController


TestViewController.m

#import "TestViewController.h"

#import "TestTwoViewController.h"

#import "BouncePresentAnimation.h"

#import "CoustomAnimator.h"

@interface TestViewController ()<UIViewControllerTransitioningDelegate,UINavigationControllerDelegate>// 1、遵守协议

@end


@implementation TestViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    self.navigationController.delegate = self;

    // Do any additional setup after loading the view.

}


-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

    if ([segue.identifier isEqualToString:@"Show TwoVC View"]) {

        TestTwoViewController *twoVC = segue.destinationViewController;

        twoVC.transitioningDelegate = self;// 4、设置TestTwoViewControllerdelegate

    }

}


-(IBAction)actNextVC:(id)sender{

    [self performSegueWithIdentifier:@"Show TwoVC View" sender:self];// 3、实现跳转到TestTwoViewControllersegue可以设置modalpush两种

}

// 2、实现<UIViewControllerTransitioningDelegate,UINavigationControllerDelegate>的协议方法

#pragma mark- UIViewControllerTransitioningDelegate

// present

- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{

    BouncePresentAnimation *animate = [[BouncePresentAnimation allocinit];

    animate.isPresenting = YES;

    return animate;

}

// dismiss

-(id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController*)dismissed{

    BouncePresentAnimation *animate = [[BouncePresentAnimation allocinit];

    animate.isPresenting = YES;

    return animate;

}

#pragma mark- UINavigationControllerDelegate

// push pop

- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController*)navigationController

                                            animationControllerForOperation:(UINavigationControllerOperation)operation

                                                         fromViewController:(UIViewController *)fromVC

                                                           toViewController:(UIViewController *)toVC{

    if (operation == UINavigationControllerOperationPush) {

        // push

        BouncePresentAnimation *animate = [[BouncePresentAnimation allocinit];

        animate.isPresenting = YES;

        return animate;

    }else{

        // pop

        BouncePresentAnimation *animate = [[BouncePresentAnimation allocinit];

        animate.isPresenting = NO;

        return animate;

    }

    

}

@end




    二、CoustomAnimator.m 遵守<UIViewControllerAnimatedTransitioning>协议,实现协议的两个方法(动画时间和动画步骤)

CoustomAnimator.m

#import "CoustomAnimator.h"

@implementation BouncePresentAnimation

// 动画时间

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext

{

    return 0.9f;

}

// 动画内容

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext

{

    if (self.isPresenting) {

        [self transitionForPresenting:transitionContext];

    }else{

        [self transitionForDismiss:transitionContext];

    }


}


-(void)transitionForPresenting:(id <UIViewControllerContextTransitioning>)transitionContext{

    // 可以看做为destination ViewController

    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    // 可以看做为source ViewController

    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    // 添加toView到容器上

    // 如果是XCode6 就可以用这段

    if ([[[UIDevice currentDevicesystemVersionfloatValue] >= 8.0)

    {

        // iOS8 SDK API

        UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];

        //UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];

        [[transitionContext containerViewaddSubview:toView];

    }else{

        // 添加toView到容器上

        [[transitionContext containerViewaddSubview:toViewController.view];

    }

    

    // 如果是XCode5 就是用这段

    [[transitionContext containerViewaddSubview:toViewController.view];

    toViewController.view.alpha = 0.0;

    //只有当fromViewController.view在最前面时给fromViewController.view添加动画才有效果,设置toViewController.view.alpha = 0.0;或者[[transitionContext containerView] sendSubviewToBack:toViewController.view];

    

    [UIView transitionWithView:fromViewController.view duration:0.9options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{

        toViewController.view.alpha = 1.0;

    } completion:^(BOOL finished) {

        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];

    }];

//    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{

//        // 动画效果有很多,这里就展示个左偏移

//        fromViewController.view.transform = CGAffineTransformMakeTranslation(-[UIScreen mainScreen].bounds.size.width, 0);

//        toViewController.view.alpha = 1.0;

//    } completion:^(BOOL finished) {

//        fromViewController.view.transform = CGAffineTransformIdentity;

//        // 声明过渡结束-->记住,一定别忘了在过渡结束时调用 completeTransition: 这个方法

//        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];

//    }];

    

}


-(void)transitionForDismiss:(id<UIViewControllerContextTransitioning>)transitionContext{

    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    

    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    

    UIView *containerView = [[UIApplication sharedApplicationkeyWindow];

    

    CGRect frame = containerView.bounds;

    frame.origin.y = - CGRectGetHeight(frame);

    

    toViewController.view.userInteractionEnabled = YES;

    

    [transitionContext.containerView addSubview:toViewController.view];

    [transitionContext.containerView addSubview:fromViewController.view];

    

    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{

        toViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeAutomatic;

        fromViewController.view.frame = frame;

    } completion:^(BOOL finished) {

        [transitionContext completeTransition:YES];

    }];

}


@end


下面具体说一下CoustomAnimator.m中实现动画具体内容这个方法

-(void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext;

在这个方法中提供了一个transitionContext,通过这个transitionContext可以拿到一个containerView,一个FromViewController以及一个ToviewController,这个containerView相当于一个画板,FromViewController.view和ToviewController.view都可以add到containerView上面,然后就可以在这三个view上实现各种各样的动画效果了。需要注意的是ToviewController.view要设置为透明或者不在最上面的一层才能看到动画效果,因为刚开始的时候我们看到的是FromViewController的view,所以FromViewController.view必须在最上面一层开始动画才有效果

   


猜你喜欢

转载自blog.csdn.net/pbz106/article/details/65443669