iOS之转场动画/自定义转场动画

<span style="color:#2f2f2f">大家都知道从iOS7开始,苹果就提供了自定义转场的API,模态推送present和dismiss、导航控制器push和pop、标签控制器的控制器切换都可以自定义转场了,</span>

 

 

    /** CATransition

     *

     *  @see http://www.dreamingwish.com/dream-2012/the-concept-of-coreanimation-programming-guide.html

     *  @see http://geeklu.com/2012/09/animation-in-ios/

     *

     *  CATransition 常用设置及属性注解如下:

     */

    

    CATransition *animation = [CATransitionanimation];

    

    /** delegate

     *

     *  动画的代理,如果你想在动画开始和结束的时候做一些事,可以设置此属性,它会自动回调两个代理方法.

     *

     *  @see CAAnimationDelegate    (按下command键点击)

     */

    

    animation.delegate =self;

    

    /** duration

     *

     *  动画持续时间

     */

    

    animation.duration = duration;

    

    /** timingFunction

     *

     *  用于变化起点和终点之间的插值计算,形象点说它决定了动画运行的节奏,比如是均匀变化(相同时间变化量相同)还是

     *  先快后慢,先慢后快还是先慢再快再慢.

     *

     *  动画的开始与结束的快慢,有五个预置分别为(下同):

     *  kCAMediaTimingFunctionLinear            线性,即匀速

     *  kCAMediaTimingFunctionEaseIn            先慢后快

     *  kCAMediaTimingFunctionEaseOut           先快后慢

     *  kCAMediaTimingFunctionEaseInEaseOut     先慢后快再慢

     *  kCAMediaTimingFunctionDefault           实际效果是动画中间比较快.

     */

    

    /** timingFunction

     *

     *  当上面的预置不能满足你的需求的时候,你可以使用下面的两个方法来自定义你的timingFunction

     *  具体参见下面的URL

     *

     *  @see http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/CAMediaTimingFunction_class/Introduction/Introduction.html

     *

     *  + (id)functionWithControlPoints:(float)c1x :(float)c1y :(float)c2x :(float)c2y;

     *

     *  - (id)initWithControlPoints:(float)c1x :(float)c1y :(float)c2x :(float)c2y;

     */

    

    animation.timingFunction = [CAMediaTimingFunctionfunctionWithName:timingFunction];

    

    /** fillMode

     *

     *  决定当前对象过了非active时间段的行为,比如动画开始之前,动画结束之后.

     *  预置为:

     *  kCAFillModeRemoved   默认,当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态

     *  kCAFillModeForwards  当动画结束后,layer会一直保持着动画最后的状态

     *  kCAFillModeBackwards 和kCAFillModeForwards相对,具体参考上面的URL

     *  kCAFillModeBoth      kCAFillModeForwards和kCAFillModeBackwards在一起的效果

     */

    

    animation.fillMode =kCAFillModeForwards;

    

    /** removedOnCompletion

     *

     *  这个属性默认为YES.一般情况下,不需要设置这个属性.

     *

     *  但如果是CAAnimation动画,并且需要设置 fillMode 属性,那么需要将 removedOnCompletion设置为NO,否则

     *  fillMode无效

     */

    

    //    animation.removedOnCompletion = NO;

    

    /** type

     *

     *  各种动画效果 其中除了'fade', `moveIn', `push' , `reveal' ,其他属于私有的API(我是这么认为的,可以点进去看下注释).

     *  ↑↑↑上面四个可以分别使用'kCATransitionFade', 'kCATransitionMoveIn', 'kCATransitionPush', 'kCATransitionReveal'来调用.

     *  @"cube"                    立方体翻滚效果

     *  @"moveIn"                  新视图移到旧视图上面

     *  @"reveal"                  显露效果(将旧视图移开,显示下面的新视图)

     *  @"fade"                    交叉淡化过渡(不支持过渡方向)             (默认为此效果)

     *  @"pageCurl"                向上翻一页

     *  @"pageUnCurl"              向下翻一页

     *  @"suckEffect"              收缩效果,类似系统最小化窗口时的神奇效果(不支持过渡方向)

     *  @"rippleEffect"            滴水效果,(不支持过渡方向)

     *  @"oglFlip"                 上下左右翻转效果

     *  @"rotate"                  旋转效果

     *  @"push"

     *  @"cameraIrisHollowOpen"    相机镜头打开效果(不支持过渡方向)

     *  @"cameraIrisHollowClose"   相机镜头关上效果(不支持过渡方向)

     */

    

    /** type

     *

     *  kCATransitionFade           交叉淡化过渡

     *  kCATransitionMoveIn         新视图移到旧视图上面

     *  kCATransitionPush           新视图把旧视图推出去

     *  kCATransitionReveal         将旧视图移开,显示下面的新视图

     */

    

    animation.type = type;

    

    /** subtype

     *

     *  各种动画方向

     *

     *  kCATransitionFromRight;     同字面意思(下同)

     *  kCATransitionFromLeft;

     *  kCATransitionFromTop;

     *  kCATransitionFromBottom;

 

       分别对应上面四个方向

 

 @“fromRight”

 

@“fromLeft”

 

@"fromTop"

 

@"fromBottom"

 

 

 

 

 

     */

 

    /** subtype

     *

     *  当type为@"rotate"(旋转)的时候,它也有几个对应的subtype,分别为:

     *  90cw    逆时针旋转90°

     *  90ccw   顺时针旋转90°

     *  180cw   逆时针旋转180°

     *  180ccw  顺时针旋转180°

     */

    

    /**

     *  type与subtype的对应关系(必看),如果对应错误,动画不会显现.

     *

     *  @see http://iphonedevwiki.net/index.php/CATransition

     */

    

    animation.subtype = subType;

    

    /**

     *  所有核心动画和特效都是基于CAAnimation,而CAAnimation是作用于CALayer的.所以把动画添加到layer上.

     *  forKey  可以是任意字符串.

     */

    

    [theView.layeraddAnimation:animationforKey:nil];

 

 

 

 

 

================

 

 

    CATransition *animation = [CATransitionanimation];//创建动画

    [animation setDuration:0.35f];//动画持续时间

    [animation setFillMode:kCAFillModeForwards];//决定当前对象过了非active时间段的行为,比如动画开始之前,动画结束之后.

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];//

用于变化起点和终点之间的插值计算,形象点说它决定了动画运行的节奏,比如是均匀变化(相同时间变化量相同)还是

     *  先快后慢,先慢后快还是先慢再快再慢.-----这个也可以自定义

 

    [animation setType:kCATransitionPush];//设置动画的效果

    [animation setSubtype:kCATransitionFromTop];//设置动画的方向

    

    [view.layeraddAnimation:animationforKey:nil];//动画添加到layer层

=======================

 

/* Common transition types. */types确定动画的类型,下面是系统提供的

 

CA_EXTERN NSString *const kCATransitionFade//退去

    CA_AVAILABLE_STARTING (10.5,2.0,9.0,2.0);

CA_EXTERN NSString *const kCATransitionMoveIn//进来

    CA_AVAILABLE_STARTING (10.5,2.0,9.0,2.0);

CA_EXTERN NSString *const kCATransitionPush//推出去

    CA_AVAILABLE_STARTING (10.5,2.0,9.0,2.0);

CA_EXTERN NSString *const kCATransitionReveal//逐步展现

    CA_AVAILABLE_STARTING (10.5,2.0,9.0,2.0);

 

/* Common transition subtypes. *///subtypes确定动画的方向

 

CA_EXTERN NSString *const kCATransitionFromRight//从右边过来

    CA_AVAILABLE_STARTING (10.5,2.0,9.0,2.0);

CA_EXTERN NSString *const kCATransitionFromLeft//从左边过来

    CA_AVAILABLE_STARTING (10.5,2.0,9.0,2.0);

CA_EXTERN NSString *const kCATransitionFromTop//从上边过来

    CA_AVAILABLE_STARTING (10.5,2.0,9.0,2.0);

CA_EXTERN NSString *const kCATransitionFromBottom//从底部过来

    CA_AVAILABLE_STARTING (10.5,2.0,9.0,2.0);

 

===================

举例:系统的

 

+ (void)animationRevealFromBottom:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setType:kCATransitionReveal];

    [animation setSubtype:kCATransitionFromBottom];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseIn]];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationRevealFromTop:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setType:kCATransitionReveal];

    [animation setSubtype:kCATransitionFromTop];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationRevealFromLeft:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setType:kCATransitionReveal];

    [animation setSubtype:kCATransitionFromLeft];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseInEaseOut]];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationRevealFromRight:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setType:kCATransitionReveal];

    [animation setSubtype:kCATransitionFromRight];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseInEaseOut]];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

 

+ (void)animationEaseIn:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setType:kCATransitionFade];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseIn]];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationEaseOut:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setType:kCATransitionFade];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    

    [view.layeraddAnimation:animationforKey:nil];

}

+ (void)animationPushUp:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    [animation setType:kCATransitionPush];

    [animation setSubtype:kCATransitionFromTop];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationPushDown:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    [animation setType:kCATransitionPush];

    [animation setSubtype:kCATransitionFromBottom];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationPushLeft:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    [animation setType:kCATransitionPush];

    [animation setSubtype:kCATransitionFromLeft];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationPushRight:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    [animation setType:kCATransitionPush];

    [animation setSubtype:kCATransitionFromRight];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

// presentModalViewController

+ (void)animationMoveUp:(UIView *)view duration:(CFTimeInterval)duration

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:duration];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseInEaseOut]];

    [animation setType:kCATransitionMoveIn];

    [animation setSubtype:kCATransitionFromTop];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

// dissModalViewController

+ (void)animationMoveDown:(UIView *)view duration:(CFTimeInterval)duration

{

    CATransition *transition = [CATransitionanimation];

    transition.duration =0.4;

    transition.timingFunction = [CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    transition.type =kCATransitionReveal;

    transition.subtype =kCATransitionFromBottom;

    [view.layeraddAnimation:transitionforKey:nil];

}

 

+ (void)animationMoveLeft:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    [animation setType:kCATransitionMoveIn];

    [animation setSubtype:kCATransitionFromLeft];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationMoveRight:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    [animation setType:kCATransitionMoveIn];

    [animation setSubtype:kCATransitionFromRight];

    

    [view.layeraddAnimation:animationforKey:nil];

}

=================举例私有的动画效果

 

+ (void)animationFlipFromTop:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    [animation setType:@"oglFlip"];

    [animation setSubtype:@"fromTop"];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationFlipFromBottom:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    [animation setType:@"oglFlip"];

    [animation setSubtype:@"fromBottom"];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationCubeFromLeft:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    [animation setType:@"cube"];

    [animation setSubtype:@"fromLeft"];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationCubeFromRight:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    [animation setType:@"cube"];

    [animation setSubtype:@"fromRight"];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationCubeFromTop:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    [animation setType:@"cube"];

    [animation setSubtype:@"fromTop"];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationCubeFromBottom:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    [animation setType:@"cube"];

    [animation setSubtype:@"fromBottom"];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationSuckEffect:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    [animation setType:@"suckEffect"];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationRippleEffect:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    [animation setType:@"rippleEffect"];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationCameraOpen:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    [animation setType:@"cameraIrisHollowOpen"];

    [animation setSubtype:@"fromRight"];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

+ (void)animationCameraClose:(UIView *)view

{

    CATransition *animation = [CATransitionanimation];

    [animation setDuration:0.35f];

    [animation setFillMode:kCAFillModeForwards];

    [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseOut]];

    [animation setType:@"cameraIrisHollowClose"];

    [animation setSubtype:@"fromRight"];

    

    [view.layeraddAnimation:animationforKey:nil];

}

 

 

 

===============================自定义转场动画

 

  1. 我们需要自定义一个遵循的<UIViewControllerAnimatedTransitioning>协议的动画过渡管理对象,并实现两个必须实现的方法: 

     //返回动画事件  
     - (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext;
     //所有的过渡动画事务都在这个方法里面完成
     - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext;
  2. 我们还需要自定义一个继承于UIPercentDrivenInteractiveTransition(这是一个继承自NSObject的类)的手势过渡管理对象,我把它成为百分比手势过渡管理对象,因为动画的过程是通过百分比控制的;
  3. 成为相应的代理,实现相应的代理方法,返回我们前两步自定义的对象就OK了 !

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

typedef NS_ENUM(NSInteger, PDAnimationType){
    
    animationTypePresent = 0,
    animationTypeDismiss ,
    animationTypePush ,
    animationTypePop,
};
NS_ASSUME_NONNULL_BEGIN

@interface PDAnimatorBaseTransition : NSObject<UIViewControllerAnimatedTransitioning>
@property (nonatomic, assign)PDAnimationType animationType;

@property (nonatomic, strong)UIView *containerView;

@property (nonatomic, strong)UIViewController *from;

@property (nonatomic, strong)UIViewController *to;

@property (nonatomic, strong)UIView *fromView;

@property (nonatomic, strong)UIView *toView;

@property (nonatomic, weak)id <UIViewControllerContextTransitioning> transitionContext;
@end

NS_ASSUME_NONNULL_END


********


#import "PDAnimatorBaseTransition.h"

@implementation PDAnimatorBaseTransition
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext{
    
    return 1.f;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{
    
    _transitionContext = transitionContext;
    
    _containerView = [transitionContext containerView];
    
    _from = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    
    _to = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    if([transitionContext respondsToSelector:@selector(viewForKey:)]){
        
        _fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
        _toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    }else{
        
        _fromView = _from.view;
        _toView = _to.view;
    }
    
    if(self.animationType == animationTypePresent){
        
        [self animationPresent];
    }else if (self.animationType == animationTypeDismiss){
        
        [self animationDismiss];
    }else if (self.animationType == animationTypePop){
        
        [self animationPop];
    }else{
        
        [self animationPush];
    }
    
}
#pragma mark -optional

//动画结束时回调
- (void)animationEnded:(BOOL) transitionCompleted{
}
- (void)animationPresent{
}
- (void)animationDismiss{
}
- (void)animationPop{
}
- (void)animationPush{
    
}
@end



********** present 

/** 
//然后我们在需要present的地方实现UIViewControllerTransitioningDelegate的代理方法
//- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{
//
//    PDAnimationPresentTransition *animationTransition = [[PDAnimationPresentTransition alloc] init];
//    animationTransition.animationType = animationTypePresent;
//    return animationTransition;
//}
//
//- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{
//
//    PDAnimationPresentTransition *animationTransition = [[PDAnimationPresentTransition alloc] init];
//    animationTransition.animationType = animationTypePresent;
//    return animationTransition;
//}
**/

#import "PDAnimatorBaseTransition.h"

NS_ASSUME_NONNULL_BEGIN

@interface PDAnimationPresentTransition : PDAnimatorBaseTransition

@end

NS_ASSUME_NONNULL_END


***********

#import "PDAnimationPresentTransition.h"

@implementation PDAnimationPresentTransition
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext{
    
    return 1.f;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{
    [super animateTransition:transitionContext];
}

- (void)animationPresent{
    
    NSTimeInterval duration = [self transitionDuration:self.transitionContext];
    __weak typeof(self) weakSelf = self;
    
    self.toView.frame = [self.transitionContext initialFrameForViewController:self.to];
    
    self.fromView.frame = [self.transitionContext initialFrameForViewController:self.from];
    
    CGAffineTransform transform = CGAffineTransformIdentity;
    transform = CGAffineTransformScale(transform, 0.001, 0.001);
  //transform =CGAffineTransformMakeRotation(M_PI/2);
    self.toView.layer.affineTransform = transform;
    
    [self.containerView addSubview:self.toView];
    
    self.toView.alpha = 0.0;
    
    [UIView animateWithDuration:duration delay:0 usingSpringWithDamping:0.6 initialSpringVelocity:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        
        self.toView.layer.affineTransform = CGAffineTransformIdentity;
        self.toView.frame = [self.transitionContext finalFrameForViewController:self.to];
        self.toView.alpha = 1.0;
    } completion:^(BOOL finished){
        
        BOOL wasCancelled = [weakSelf.transitionContext transitionWasCancelled];
        [weakSelf.transitionContext completeTransition:!wasCancelled];
    }];
    
}
@end


********push
/**
//然后我们在需要push的地方实现UINavigationControllerDelegate的协议方法:
//
//- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
//animationControllerForOperation:(UINavigationControllerOperation)operation
//fromViewController:(UIViewController *)fromVC
//toViewController:(UIViewController *)toVC NS_AVAILABLE_IOS(7_0){
//
//    PDAnimatorPUshPopTransition *animationTransition = [[PDAnimatorPUshPopTransition alloc] init];
//    if(operation == UINavigationControllerOperationPush){
//
//        animationTransition.animationType = animationTypePush;
//    }else if (operation == UINavigationControllerOperationPop){
//
//        animationTransition.animationType = animationTypePop;
//    }
//
//    NSArray *indexPaths = [self.collectionView indexPathsForSelectedItems];
//    if (indexPaths.count == 0) {
//        return nil;
//    }
//
//    NSIndexPath *selectedIndexPath = indexPaths[0];
//    UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:selectedIndexPath];
//
//    // 一定要加上convertPoint:toView:操作
//    animationTransition.itemCenter = [self.collectionView convertPoint:cell.center toView:self.view];
//    animationTransition.itemSize = cell.frame.size;
//    animationTransition.imageName = [NSString stringWithFormat:@"%ld", (long)selectedIndexPath.item];
//
//    return animationTransition;
//}
**/
#import "PDAnimatorBaseTransition.h"

#import <UIKit/UIKit.h>

@interface PDAnimatorPUshPopTransition : PDAnimatorBaseTransition
@property (nonatomic, assign)CGPoint itemCenter;

@property (nonatomic, assign)CGSize itemSize;

@property (nonatomic, strong)NSString *imageName;

@end


******

#import "PDAnimatorPUshPopTransition.h"

@implementation PDAnimatorPUshPopTransition
- (instancetype)init{
    
    self = [super init];
    if(self){
        
        
    }
    
    return self;
}

- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext{
    
    return 5.f;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{
    
    [super animateTransition:transitionContext];
}

- (void)animationPush{
    
    NSTimeInterval duration = [self transitionDuration:self.transitionContext];
    __weak typeof(self) weakSelf = self;
    
    self.containerView.backgroundColor = [UIColor lightGrayColor];
    
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 160)];
    imageView.image = [UIImage imageNamed:self.imageName];
    imageView.center = _itemCenter;
    
    CGFloat initialScale = _itemSize.width / CGRectGetWidth(imageView.frame);
    
    CGAffineTransform transform = CGAffineTransformIdentity;
    
    transform = CGAffineTransformScale(transform, initialScale, initialScale);
    transform = CGAffineTransformRotate(transform, M_PI);
    
    imageView.layer.affineTransform = transform;
    
    // imageView.transform = CGAffineTransformMakeScale(initialScale, initialScale);
    
    [self.containerView addSubview:imageView];
    
    
    self.toView.frame = [self.transitionContext finalFrameForViewController:self.to];
    CGPoint finalCenter = self.toView.center;
    self.toView.center = finalCenter;
    self.toView.alpha = 0.0;
    //这一句一定要
    [self.containerView addSubview:self.toView];
    
    [UIView animateWithDuration:duration delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:0 options:UIViewAnimationOptionCurveLinear animations:^{
        
        
        imageView.layer.affineTransform = CGAffineTransformIdentity;
        
        imageView.center = finalCenter;
        
        self.fromView.alpha = 0.0;
        self.containerView.backgroundColor = [UIColor redColor];
    } completion:^(BOOL finished){
        
        [imageView removeFromSuperview];
        
        weakSelf.toView.alpha = 1.0f;
        weakSelf.fromView.alpha = 1.0f;
        
        [weakSelf.transitionContext completeTransition:![weakSelf.transitionContext transitionWasCancelled]];
    }];
    
}

- (void)animationPop{
    
    NSTimeInterval duration = [self transitionDuration:self.transitionContext];
    __weak typeof(self) weakSelf = self;
    
    self.toView.frame = [self.transitionContext finalFrameForViewController:self.to];
    
    [self.containerView insertSubview:self.toView belowSubview:self.fromView];
    
    self.fromView.alpha = 0.0;
    
    self.fromView.backgroundColor = [UIColor clearColor];
    
    [UIView animateWithDuration:duration delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:0 options:UIViewAnimationOptionCurveLinear animations:^{
        
        CGFloat initialScale = _itemSize.width / 200;
        weakSelf.fromView.transform = CGAffineTransformMakeScale(initialScale, initialScale);
        weakSelf.fromView.center = weakSelf.itemCenter;
        
        weakSelf.toView.alpha = 1.0f;
    } completion:^(BOOL finished){
        
        weakSelf.fromView.alpha = 0.0f;
        
        [weakSelf.transitionContext completeTransition:![weakSelf.transitionContext transitionWasCancelled]];
    }];
}


@end

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值