IOS 抽屉效果
原创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 协议,并且负责实际执行动画。
(2)交互控制器 (Interaction Controllers) 通过遵从 UIViewControllerInteractiveTransitioning 协议来控制可交互式的转场。
(3)转场代理 (Transitioning Delegates) 根据不同的转场类型方便的提供需要的动画控制器和交互控制器。
(4)转场上下文 (Transitioning Contexts) 定义了转场时需要的元数据,比如在转场过程中所参与的视图控制器和视图的相关属性。 转场上下文对象遵从 UIViewControllerContextTransitioning 协议,并且这是由系统负责生成和提供的。
(5)转场协调器(Transition Coordinators) 可以在运行转场动画时,并行的运行其他动画。 转场协调器遵从 UIViewControllerTransitionCoordinator 协议。
动画交互器由UIPercentDrivenInteractiveTransition提供
动画控制器由自定义一个类Animator,遵循UIViewControllerAnimatedTransitioning来提供,这个协议有两个必须实现的函数,就是代码中的两个函数。
这么做的好处就是动画本身的过程和ViewController解耦
BTY:demo仍然有些不完善的地方,等有时间了我再优化下
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。