Objective_C 控制器跳转动画

一、创建一个UIViewController的分类即可:

1、h文件

#import <UIKit/UIKit.h>

typedef NS_ENUM (NSInteger, ZJPushType)   {

    //push

    leftToRight  = 1,

    centerToEdge = 3,

    topToBottom  = 5,

    diagonalEnlarge = 7,

    // pop

    rightToLeft  = 2,

    edgeToCenter = 4,

    bottomToTop  = 6,

    diagonalNarrow  = 8,

};

#import <Foundation/Foundation.h>

@interface ZJPushAnimation : NSObject<UIViewControllerAnimatedTransitioning>

-(instancetype)initWithPushType:(ZJPushType)type;

@end

typedef NS_ENUM (NSInteger, ZJStartOrEndPath)   {

    startPath  = 1,

    endPath    = 2,

};

@interface UIViewController (PushAnimation)

-(void)pushViewController:(UIViewController *)viewController animation:(ZJPushType)animation;

-(UIViewController *)popViewControllerAnimation:(ZJPushType)animation;

@end


2、m文件

#import "UIViewController+PushAnimation.h"

#import <objc/runtime.h>

@interface UIViewController ()<UINavigationControllerDelegate>

@property(nonatomic,assign) ZJPushType animation;

@end

@implementation UIViewController (PushAnimation)

-(void)setAnimation:(ZJPushType)animation{

    objc_setAssociatedObject(self, @selector(animation), @(animation), OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

-(ZJPushType)animation{

    return [objc_getAssociatedObject(self@selector(animation)) integerValue];

}

-(void)pushViewController:(UIViewController *)viewController animation:(ZJPushType)animation{

    self.navigationController.delegate = self;

    [self setAnimation:animation];

    [self.navigationController pushViewController:viewController animated:YES];

}

-(UIViewController *)popViewControllerAnimation:(ZJPushType)animation{

    self.navigationController.delegate = self;

    [self setAnimation:animation];

    return  [self.navigationController popViewControllerAnimated:YES];

}

#pragma mark -- UINavigationControllerDelegate --

- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{

    self.navigationController.delegate  = nil;

    return [[ZJPushAnimation alloc] initWithPushType:self.animation];

}

-(void)dealloc{

    self.navigationController.delegate  = nil;

}

@end


@interface ZJPushAnimation()<CAAnimationDelegate>

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

@property(nonatomic,assign) ZJPushType pushType;

@end

@implementation ZJPushAnimation

#pragma mark -- UIViewControllerAnimatedTransitioning --

-(instancetype)initWithPushType:(ZJPushType)type{

    if(self == [super init]){

        self.pushType = type;

    }

    return self;

}


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

    return 0.3;

}

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

    

    self.transitionContext = transitionContext;

    

    //获取源控制器 注意不要写成 UITransitionContextFromViewKey

    UIViewController *fromVc = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    //获取目标控制器 注意不要写成 UITransitionContextToViewKey

    UIViewController *toVc = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    

    //获得容器视图

    UIView *containView = [transitionContext containerView];

    // 都添加到container中。注意顺序 目标控制器的view需要后面添加

    if(self.pushType%2 == 1){

        [containView addSubview:fromVc.view];

        [containView addSubview:toVc.view];

    }else{

        [containView addSubview:toVc.view];

        [containView addSubview:fromVc.view];

    }

    //

    UIBezierPath *startPath = [self pathWithPushType:self.pushType StartOrEnd:1];

    UIBezierPath *endPath = [self pathWithPushType:self.pushType StartOrEnd:2];

    //赋值给toVc视图layer的mask

    CAShapeLayer *maskLayer = [CAShapeLayer layer];

    maskLayer.path = endPath.CGPath;

    if(self.pushType%2 == 1)toVc.view.layer.mask = maskLayer;

    if(self.pushType%2 == 0)fromVc.view.layer.mask = maskLayer;

    

    CABasicAnimation *maskAnimation =[CABasicAnimation animationWithKeyPath:@"path"];

    maskAnimation.fromValue = (__bridge id)startPath.CGPath;

    maskAnimation.toValue = (__bridge id)endPath.CGPath;

    maskAnimation.duration = [self transitionDuration:transitionContext];

    maskAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    maskAnimation.delegate = self;

    [maskLayer addAnimation:maskAnimation forKey:@"path"];

}


#pragma mark -- CAAnimationDelegate --

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{

    //告诉 iOS 这个 transition 完成

    [self.transitionContext completeTransition:YES];

    [self.transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view.layer.mask = nil;

    [self.transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view.layer.mask = nil;

}

#pragma mark - Animations

/**

 * @prarm pushType 跳转类型

 * @prarm pathType 开始或者结尾

 */

-(UIBezierPath *)pathWithPushType:(ZJPushType)pushType StartOrEnd:(ZJStartOrEndPath)pathType{

    CGSize screenSize = [UIScreen mainScreen].bounds.size;

    UIBezierPath * path = [UIBezierPath bezierPath];

    if(pushType == 1){ // leftToRight

        if(pathType == 1){

            path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 1, screenSize.height)];

        }else{

            path =  [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, screenSize.width, screenSize.height)];

        }

    }else if(pushType == 2){ // rightToLeft

        if(pathType == 1){

            path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, screenSize.width, screenSize.height)];

        }else{

            path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 1, screenSize.height)];

        }

    }else if(pushType == 3){ // centerToEdge

        CGRect subFrame = CGRectMake(screenSize.width*0.5, screenSize.height*0.5, 0, 0);

        if(pathType == 1){

            path = [UIBezierPath bezierPathWithOvalInRect:subFrame];

        }else{

            CGFloat radius = sqrt(screenSize.width*0.5*screenSize.width*0.5+screenSize.height*0.5*screenSize.height*0.5);

            path = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(subFrame, -radius, -radius)];

        }

    }else if(pushType == 4){ // edgeToCenter

        CGSize screenSize = [UIScreen mainScreen].bounds.size;

        CGRect subFrame = CGRectMake(screenSize.width*0.5, screenSize.height*0.5, 0, 0);

        if(pathType == 1){

            // sqrt函数表示开平方根

            CGFloat radius = sqrt(screenSize.width*0.5*screenSize.width*0.5+screenSize.height*0.5*screenSize.height*0.5);

            path = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(subFrame, -radius, -radius)];

        }else{

            //绘制圆形

            path = [UIBezierPath bezierPathWithOvalInRect:subFrame];

        }

    }else if(pushType == 5){ // topToBottom

        if(pathType == 1){

            path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, screenSize.width, 1)];

        }else{

            path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, screenSize.width, screenSize.height)];

        }

    }else if(pushType == 6){ // bottomToTop

        if(pathType == 1){

            path =  [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, screenSize.width, screenSize.height)];

        }else{

            path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, screenSize.width, 1)];

        }

    }else if(pushType == 7){ // diagonalEnlarge

        if(pathType == 1){

            path = [UIBezierPath bezierPathWithRect:CGRectMake(screenSize.width, screenSize.height, 0, 0)];

        }else{

            path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, screenSize.width, screenSize.height)];

        }

    }else if(pushType == 8){ // diagonalNarrow

        if(pathType == 1){

            path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, screenSize.width, screenSize.height)];

        }else{

            path = [UIBezierPath bezierPathWithRect:CGRectMake(screenSize.width, screenSize.height,0, 0)];

        }

    }

    return path;

}

@end



  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值