原创Blog,转载请注明出处
先看看Demo效果
视频链接如下
http://v.youku.com/v_show/id_XODc1OTQwODQ0.html
实现过程如下
1 新建一个基于单视图的工程。拖入两个ViewController,为了区分,在大纲中改为firstViewController 和 SecondViewController。沿着图中红线control+拖拽,在弹出的窗口中选择Show
@interface NavigationControllerDelegate : NSObject<UINavigationControllerDelegate>
NavigationControllerDelegate.h
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface NavigationControllerDelegate : NSObject<UINavigationControllerDelegate> @end
NavigationControllerDelegate.m
#import "NavigationControllerDelegate.h" #import "Animator.h" @interface NavigationControllerDelegate()<UIGestureRecognizerDelegate> @property (strong,nonatomic)UIPercentDrivenInteractiveTransition * interactivcTransition; @property (weak, nonatomic) IBOutlet UINavigationController *nav; @property (strong,nonatomic) UIPanGestureRecognizer * pangesture; @end @implementation NavigationControllerDelegate //添加手势 -(void)awakeFromNib{ self.pangesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(paned:)]; [self.nav.view addGestureRecognizer:self.pangesture]; } //响应手势 - (void)paned:(UIPanGestureRecognizer *)sender { if (self.nav == nil){ return; } CGPoint translation; switch (sender.state) { case UIGestureRecognizerStateBegan: { _interactivcTransition = [[UIPercentDrivenInteractiveTransition alloc] init]; if (self.nav.viewControllers.count > 1) { [self.nav popViewControllerAnimated:YES]; } else{ [self.nav.topViewController performSegueWithIdentifier:@"PushSegue" sender:nil]; } } break; case UIGestureRecognizerStateChanged: translation = [sender translationInView:self.nav.view]; if (self.nav.viewControllers.count > 1 && translation.x > 0) { CGFloat completionProgress = translation.x/CGRectGetWidth(self.nav.view.frame); [self.interactivcTransition updateInteractiveTransition:completionProgress]; } if (self.nav.viewControllers.count == 1 && translation.x < 0) { CGFloat completionProgress = -translation.x/CGRectGetWidth(self.nav.view.frame); [self.interactivcTransition updateInteractiveTransition:completionProgress]; } break; case UIGestureRecognizerStateEnded: if (self.nav.viewControllers.count >1 && [sender velocityInView:self.nav.view].x>0) { [self.interactivcTransition finishInteractiveTransition]; }else if(self.nav.viewControllers.count <= 1 && [sender velocityInView:self.nav.view].x<0){ [self.interactivcTransition finishInteractiveTransition]; }else{ [self.interactivcTransition cancelInteractiveTransition]; } break; case UIGestureRecognizerStateCancelled: [self.interactivcTransition cancelInteractiveTransition]; break; default: [self.interactivcTransition cancelInteractiveTransition]; self.interactivcTransition = nil; break; } } //NavigationController代理-决定了动画交互过程由哪个对象控制 - (id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>) animationController{ return self.interactivcTransition; } //NavigationController代理-决定了如何呈现动画 -(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC { return [[Animator alloc] init]; } @end
// Animator.h
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface Animator : NSObject <UIViewControllerAnimatedTransitioning> @end
// Animator.m
// // Animator.m // HwcFoundationExample // // Created by huangwenchen on 15/1/20. // Copyright (c) 2015年 huangwenchen. All rights reserved. // #import "Animator.h" @implementation Animator //动画时间 - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext { return 0.8; } //动画的过程 - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext { UIViewController* fromviewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; UINavigationController * nav = toViewController.navigationController; CGRect originFrame = toViewController.view.frame; CGRect offSetFrame = CGRectOffset(originFrame,-CGRectGetWidth(originFrame), 0); if (nav.viewControllers.count > 1) { [[transitionContext containerView] addSubview:toViewController.view]; toViewController.view.frame = offSetFrame; [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ toViewController.view.frame = originFrame; } completion:^(BOOL finished) { [transitionContext completeTransition:![transitionContext transitionWasCancelled]]; }]; }else { [[transitionContext containerView] insertSubview:toViewController.view belowSubview:fromviewController.view]; fromviewController.view.frame = originFrame; [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ fromviewController.view.frame = offSetFrame; } completion:^(BOOL finished) { [transitionContext completeTransition:![transitionContext transitionWasCancelled]]; }]; } } @end第二部分
(1)动画控制器 (Animation Controllers) 遵从 UIViewControllerAnimatedTransitioning 协议,并且负责实际执行动画。
动画交互器由UIPercentDrivenInteractiveTransition提供
动画控制器由自定义一个类Animator,遵循UIViewControllerAnimatedTransitioning来提供,这个协议有两个必须实现的函数,就是代码中的两个函数。
这么做的好处就是动画本身的过程和ViewController解耦
BTY:demo仍然有些不完善的地方,等有时间了我再优化下
原文地址:http://blog.csdn.net/hello_hwc/article/details/42978155