自定义UINavigationController 切换动画

//

//  NavControllerDelegate.h

//  WZKPonyBiJi

//

//  Created by 王正魁 on 15-3-17.

//  Copyright (c) 2015 psylife. All rights reserved.

//


#import <Foundation/Foundation.h>

#import "Animator.h"

#import "Animations.h"

#import <UIKit/UIKit.h>

typedef enum

{

    //以下是枚举成员

    TestA = 0,//缩小渐变

    TestB,//下退渐变

    

    

}animationType;

@interface NavControllerDelegate : NSObject <UINavigationControllerDelegate,UIViewControllerTransitioningDelegate>

+ (NavControllerDelegate *) sharedInstance;

@property (strong, nonatomic) IBOutlet UINavigationController *navigationController;

@property(nonatomic,strong)UIPinchGestureRecognizer *pinchRecognizer;

@property (nonatomic, assign) animationType animationForTransition;

-(void)addtag;

@end

/*

 NavControllerDelegate* nav = [NavControllerDelegate sharedInstance];//初始化导航控制器动画

 MainViewController* main = [[MainViewController alloc] init];

 nav.navigationController = [[UINavigationController alloc] initWithRootViewController:main];//常见有动画的导航控制器

 [nav addtag];//将动画和手势加到导航控制器上

 */




//------------------------------------------------------




//

//  NavControllerDelegate.m

//  WZKPonyBiJi

//

//  Created by 王正魁 on 15-3-17.

//  Copyright (c) 2015 psylife. All rights reserved.

//


#import "NavControllerDelegate.h"


@interface NavControllerDelegate ()

{

    CGFloat _startScale;

}

@property (strong, nonatomic) Animator* animator;

@property (strong, nonatomic) Animations* animatorBack;

@property (strong, nonatomic) UIPercentDrivenInteractiveTransition* interactionController;


@end

@implementation NavControllerDelegate

//将当前对象设置成单例模式

static NavControllerDelegate * sharedSingleton = nil;


+ (NavControllerDelegate *) sharedInstance

{

    if (sharedSingleton == nil) {

        sharedSingleton = [[NavControllerDelegate alloc] init];

      

    }

    return sharedSingleton;

}

//添加手势

-(void)addtag

{

    UIPanGestureRecognizer* panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];

    [self.navigationController.view addGestureRecognizer:panRecognizer];

    

    _pinchRecognizer = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinch:)];

    

    [self.navigationController.view addGestureRecognizer:_pinchRecognizer];

    

    

    self.navigationController.delegate = self;

    self.animator = [Animator new];//穿件动画对象

    self.animatorBack = [Animations new];

}

/*

 UIPercentDrivenInteractiveTransition---

 手势和动画结合的控制类,

 现在我们可以识别该手势了,我们用它来设置并更新一个 iOS 7 新加入的类的对象。 UIPercentDrivenInteractiveTransition。这个类的对象会根据我们的手势,来决定我们的自定义过渡的完成度。我们把这些都放到手势识别器的 action 方法中去,具体就是:

 

 当手势刚刚开始,我们创建一个 UIPercentDrivenInteractiveTransition 对象,然后让 navigationController 去把当前这个 viewController 弹出。

 

 当手慢慢划入时,我们把总体手势划入的进度告诉 UIPercentDrivenInteractiveTransition 对象。

 

 当手势结束,我们根据用户的手势进度来判断过渡是应该完成还是取消并相应的调用 finishInteractiveTransition 或者 cancelInteractiveTransition 方法.

 */

-(void)handlePinch:(UIPinchGestureRecognizer *)pinch {

    CGFloat scale = pinch.scale;

    switch (pinch.state) {

        case UIGestureRecognizerStateBegan: {

            self.interactionController = [UIPercentDrivenInteractiveTransition new];

            _startScale = scale;

            //            [self.interactionController isInteractive];

            if (self.navigationController.viewControllers.count > 1) {

                [self.navigationController popViewControllerAnimated:YES];

            }

            

            break;

        }

        case UIGestureRecognizerStateChanged: {

            CGFloat percent = (1.0 - scale/_startScale);

            [self.interactionController updateInteractiveTransition:(percent < 0.0) ?

             0.0 : percent];

            break;

        }

        case UIGestureRecognizerStateEnded: {

            CGFloat percent = (1.0 - scale/_startScale);

            BOOL cancelled = ([pinch velocity] < 5.0 && percent

                              <= 0.3);

            if (cancelled)

            {

                [self.interactionController cancelInteractiveTransition];

            }

            else

            {

                [self.interactionController finishInteractiveTransition];

            }

            self.interactionController = nil;

            break;

        }

        case UIGestureRecognizerStateCancelled: {

            CGFloat percent = (1.0 - scale/_startScale);

            BOOL cancelled = ([pinch velocity] < 5.0 && percent

                              <= 0.3);

            if (cancelled) {

                [self.interactionController cancelInteractiveTransition];

            }

            else{

                [self.interactionController finishInteractiveTransition];

            }

            self.interactionController = nil;

            break;

        }

    }

}


- (void)pan:(UIPanGestureRecognizer*)recognizer

{

    UIView* view = self.navigationController.view;

    if (recognizer.state == UIGestureRecognizerStateBegan) {

        CGPoint location = [recognizer locationInView:view];

        if (location.xCGRectGetMidX(view.bounds) && self.navigationController.viewControllers.count > 1) { // left half

            self.interactionController = [UIPercentDrivenInteractiveTransition new];

            [self.navigationController popViewControllerAnimated:YES];

        }

        else if (location.xCGRectGetMaxX(view.bounds) && self.navigationController.viewControllers.count > 1)

        {

            self.interactionController = [UIPercentDrivenInteractiveTransition new];

            [self.navigationController popViewControllerAnimated:YES];

        }

    } else

        if (recognizer.state == UIGestureRecognizerStateChanged) {

        CGPoint translation = [recognizer translationInView:view];

        CGFloat d = fabs(translation.x / CGRectGetWidth(view.bounds));

        [self.interactionController updateInteractiveTransition:d];

    } else

        if (recognizer.state == UIGestureRecognizerStateEnded) {

        if ([recognizer velocityInView:view].x > 0) {

            [self.interactionController finishInteractiveTransition];

        } else {

            [self.interactionController cancelInteractiveTransition];

        }

        self.interactionController = nil;

    }

}

//pushpop时调用的代理方法

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

{

    if (operation == UINavigationControllerOperationPop) {

        

//        [self selectAnimation];

        return self.animator;

    }

    if (operation == UINavigationControllerOperationPush) {

//        [self selectAnimation];

        return self.animatorBack;

    }

    return nil;

}

//UINavigationController交互动画,返回

- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController

{

    return self.interactionController;

}

-(id<UIViewControllerAnimatedTransitioning>)selectAnimation

{

    switch (self.animationForTransition) {

        case TestA:

            return self.animator;

            break;

        case TestB:

            return self.animatorBack;

            break;

            

        default:

            return nil;

            break;

    }

}


/*

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

{

    return self.animator;

}


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

{

    return self.animatorBack;

}

*/


@end


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值