iOS 转场动画笔记

文章转载出自: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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值