转场动画3-手势返回

拉段子,扯犊子咱不会,代码讲解走起
推荐一篇关于转场动画的文章地址,写的很好
附上该文章的DemoGithub

前提:理解手势只是触发方式,关键不在于手势,手势的状态改变和transition中各个状态做关联,构成手动控制转场的关键(可能不知道我在说什么,看代码理解)

**手势状态:**
 UIGestureRecognizerStatePossible,   // the recognizer has not yet recognized its gesture, but may be evaluating touch events. this is the default state
    
    UIGestureRecognizerStateBegan,      // the recognizer has received touches recognized as the gesture. the action method will be called at the next turn of the run loop
    UIGestureRecognizerStateChanged,    // the recognizer has received touches recognized as a change to the gesture. the action method will be called at the next turn of the run loop
    UIGestureRecognizerStateEnded,      // the recognizer has received touches recognized as the end of the gesture. the action method will be called at the next turn of the run loop and the recognizer will be reset to UIGestureRecognizerStatePossible
    UIGestureRecognizerStateCancelled,  // the recognizer has received touches resulting in the cancellation of the gesture. the action method will be called at the next turn of the run loop. the recognizer will be reset to UIGestureRecognizerStatePossible
    
    UIGestureRecognizerStateFailed,     // the recognizer has received a touch sequence that can not be recognized as the gesture. the action method will not be called and the recognizer will be reset to UIGestureRecognizerStatePossible
    
    // Discrete Gestures – gesture recognizers that recognize a discrete event but do not report changes (for example, a tap) do not transition through the Began and Changed states and can not fail or be cancelled
    UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded // the recognizer has received touches recognized as the gesture. the action method will be called at the next turn of the run loop and the recognizer will be reset to UIGestureRecognizerStatePossible

主要用到的:

UIGestureRecognizerStateBegan
UIGestureRecognizerStateChanged
UIGestureRecognizerStateCancelled
UIGestureRecognizerStateEnded

码上

//
//  PopViewController.m
//  转场动画2-Pop
//
//  Created by MAc on 16/5/28.
//  Copyright © 2016年 李赵杰. All rights reserved.
//

#import "PopViewController.h"
#import "PopTransition.h"
@interface PopViewController ()<UINavigationControllerDelegate>{
    
    /*! This subclass of UIPanGestureRecognizer only recognizes if the user slides their finger
     in from the bezel(韧角) on the specified edge. */
    UIScreenEdgePanGestureRecognizer * pan;
    //这个类的对象会根据我们的手势,来决定我们的自定义过渡的完成度。我们把这些都放到手势识别器的 action 方法中去
    UIPercentDrivenInteractiveTransition * interactionTransition;
}

@end

@implementation PopViewController
- (void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    self.navigationController.delegate = self;

}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    
    // Stop being the navigation controller's delegate
    if (self.navigationController.delegate == self) {
        self.navigationController.delegate = nil;
    }
}
- (void)viewDidLoad {
    [super viewDidLoad];
    pan = [[UIScreenEdgePanGestureRecognizer alloc]initWithTarget:self action:@selector(handlEdgeScreenPanGesture:)];
    pan.edges = UIRectEdgeLeft;
    [self.view addGestureRecognizer:pan];
    self.view.backgroundColor = [UIColor redColor];
      // Do any additional setup after loading the view.
}
-(void)handlEdgeScreenPanGesture:(UIScreenEdgePanGestureRecognizer *)gerture{
     // translation in the coordinate system of the specified view
    NSLog(@"x position is %f",[gerture translationInView:self.view].x);
   // CGFloat progress = [gerture translationInView:self.view].x/(1.0*CGRectGetWidth(self.view.bounds));
    CGFloat progress = [gerture translationInView:self.view].x / (self.view.bounds.size.width * 1.0);
     progress = MIN(1.0, MAX(0.0, progress));
    switch (gerture.state) {
        case UIGestureRecognizerStateBegan:
            interactionTransition = [[UIPercentDrivenInteractiveTransition alloc]init];
            [self.navigationController popViewControllerAnimated:YES];
            break;
        case UIGestureRecognizerStateChanged:
            [interactionTransition updateInteractiveTransition:progress];
            break;
        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateCancelled:{
            if (progress > 0.5) {
                [interactionTransition finishInteractiveTransition];
            }else{
                [interactionTransition cancelInteractiveTransition];
            }
            interactionTransition = nil;
            break;
        }
        default:
            break;
    }
    
}
- (nullable id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
                                   interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>) animationController {
    if ([animationController isKindOfClass:[PopTransition class]]) {
        return interactionTransition;
    }else
        return nil;
}
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{
    if (fromVC == self&&operation == UINavigationControllerOperationPop) {
        return [[PopTransition alloc]init];
    }
    return nil;
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

Demo下载地址

posted @ 2016-05-29 22:39  严_青  阅读(306)  评论(0编辑  收藏  举报