iOS 转场动画

首先看一个简单的 效果图
模拟器不知道怎么了 变得这么慢,就将就着看吧


iOS 转场动画_第1张图片
转场动画.gif

关于转场动画我们主要考虑两个,一个是导航条中的 转场就是(push、pop) ,另外一个就是 present 和dismiss

1. push、pop 的转场

关于push 和 pop 我们首先要先设置self.navigationController.delegate = self; (这个self 就是 VC控制器),然后我们找到这个导航条的代理

- (id) navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
    
    if (operation == UINavigationControllerOperationPush) {
        
        return _pushAnimation;
        
    }else if (operation == UINavigationControllerOperationPop) {
        
        return _popAnimation;
    }else{
        
        return nil;
        
    }
    
}

这里面的_pushAnimation 和 _popAnimation是我接下来需要讲的动画。

PushAnimation 的设置 (PopAnimation 其实也是一样)

这里首先要 实现 UIViewControllerAnimatedTransitioning 这个ios7 以后的一个代理,然后我们找到这个delegate 中的两个必须实现的方法 1.- (NSTimeInterval)transitionDuration:(id)transitionContext 显然这个是返回动画时间的代理;- (void)animateTransition:(id)transitionContext,就是把一些动画的交互写在这里

//
//  PushAnimation.h
//  转场动画
//
//  Created by apple on 16/6/22.
//  Copyright © 2016年 李重阳. All rights reserved.
//

#import 
#import 

@interface PushAnimation : NSObject


@end
//
//  PushAnimation.m
//  转场动画
//
//  Created by apple on 16/6/22.
//  Copyright © 2016年 李重阳. All rights reserved.
//

#import "PushAnimation.h"


@implementation PushAnimation

/* 动画持续的时间 **/
- (NSTimeInterval)transitionDuration:(id)transitionContext {
    
    return 1.0;
}

/*动画交互 **/
- (void)animateTransition:(id)transitionContext {
    
    //目的ViewController
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    //起始ViewController
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    //添加toView到上下文的视图中
    UIView * containerView = [transitionContext containerView];
    /* 加入 目的 控制器的View**/
    [containerView addSubview:toViewController.view];
    [containerView bringSubviewToFront:fromViewController.view];
    
    //自定义动画
    toViewController.view.transform = CGAffineTransformMakeTranslation(-320, 0);
    
    [UIView animateWithDuration:[self transitionDuration:transitionContext]
                     animations:^{
        
        fromViewController.view.transform = CGAffineTransformMakeTranslation(320, 0);
        toViewController.view.transform = CGAffineTransformIdentity;
        
    } completion:^(BOOL finished) {
            
        fromViewController.view.transform = CGAffineTransformIdentity;
        // 声明过渡结束时调用 completeTransition: 这个方法
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
            
    }];

}


@end


2. present 和dismiss 的转场

其实和pop 差不多 只不过有两点不同
1.控制器需要实现UIViewControllerTransitioningDelegate这个代理
2.就是在转场的时候 当dismiss 的时候 要UIView * snapshotView = [fromViewController.view snapshotViewAfterScreenUpdates:YES];截个 源控制器的屏,可能是因为dismiss 后源控制器马上释放掉了。

- (IBAction)present:(id)sender {
    
    UIStoryboard * storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    ViewController3 * vc3 = [storyboard instantiateViewControllerWithIdentifier:@"ViewController3"];
    vc3.transitioningDelegate = self;
    [self presentViewController:vc3 animated:YES completion:nil];
    
}

#pragma mark - UIViewControllerTransitioningDelegate

-(id)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
    
    _presentOrDismissAnimation.animationType = AnimationTypePresent;
    return _presentOrDismissAnimation;
    
}

-(id)animationControllerForDismissedController:(UIViewController *)dismissed {

    _presentOrDismissAnimation.animationType = AnimationTypeDismiss;
    return _presentOrDismissAnimation;
}
//
//  PresentOrDismissAnimation.h
//  转场动画
//
//  Created by apple on 16/6/22.
//  Copyright © 2016年 李重阳. All rights reserved.
//

#import 
#import 

typedef enum {
    
    AnimationTypePresent,
    AnimationTypeDismiss
    
} AnimationType;


@interface PresentOrDismissAnimation : NSObject

@property (nonatomic, assign) AnimationType animationType;

@end
//
//  PresentOrDismissAnimation.m
//  转场动画
//
//  Created by apple on 16/6/22.
//  Copyright © 2016年 李重阳. All rights reserved.
//

#import "PresentOrDismissAnimation.h"

@implementation PresentOrDismissAnimation


- (NSTimeInterval)transitionDuration:(id)transitionContext {
    
    return 3;
}

- (void)animateTransition:(id)transitionContext {
    
    //目的ViewController
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    //起始ViewController
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    
    //添加toView到上下文的视图中
    UIView * containerView = [transitionContext containerView];
    [containerView addSubview:toViewController.view];
    
    if (self.animationType == AnimationTypePresent) {
        
        toViewController.view.transform = CGAffineTransformMakeTranslation(0, -568);
        //进行动画
        [UIView animateWithDuration:[self transitionDuration:transitionContext]
                              delay:0
             usingSpringWithDamping:.5
              initialSpringVelocity:.6
                            options:UIViewAnimationOptionCurveLinear
                         animations:^{
            
            toViewController.view.transform = CGAffineTransformIdentity;
            
        } completion:^(BOOL finished) {
            
            [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
            
        }];
        
        
    }else {
        
        /* dismiss 的时候 fromView 会马上消失掉了,所以先截个屏幕**/
        UIView * snapshotView = [fromViewController.view snapshotViewAfterScreenUpdates:YES];
        [transitionContext.containerView addSubview:snapshotView];
        
        //进行动画
        [UIView animateWithDuration:[self transitionDuration:transitionContext]
                              delay:0
             usingSpringWithDamping:0.5
              initialSpringVelocity:0
                            options:UIViewAnimationOptionCurveLinear
                         animations:^{
            
            snapshotView.transform = CGAffineTransformMakeTranslation(0, 568);
            
        } completion:^(BOOL finished) {
            
            [snapshotView removeFromSuperview];
            //结束Transition
            [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
        }];
    }
    
}


@end

可以戳这里下载上面的代码

你可能感兴趣的:(iOS 转场动画)