原创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