手势

手势识别介绍


手势_第1张图片
Touch机制实现


手势_第2张图片
touch机制实现(操作复杂)

注:正确的打开方式:手势识别


手势_第3张图片
进行封装



手势_第4张图片
手势识别通过这个类来使用(将手势识别封装,抽象了出来)



手势_第5张图片


手势_第6张图片
UIKIt继承了父类UIGestureRecognizer,实现了很多子类

手势识别步骤


手势_第7张图片


手势_第8张图片
点击手势参数


手势_第9张图片
右侧,(按下,松开)


手势_第10张图片
右侧,移动的时候会一直调changed状态,来电话中断会调用cancelled状态,松开会调用Recognized状态


手势_第11张图片

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

        [_testView addGestureRecognizer:panGesture];

- (void)pan:(UIPanGestureRecognizer *)gesture

{

    CGPointtranslatePoint = [gesturetranslationInView:self.view];

    _testView.center = CGPointMake(_testView.center.x + translatePoint.x, _testView.center.y + translatePoint.y);//计算的距离会从初始位置开始算起,所以移动的距离会变大,只有重置这个才行

    [gesturesetTranslation:CGPointZero inView:self.view];//重置这个偏移量


    if (gesture.state == UIGestureRecognizerStatePossible)

    {

        NSLog(@"possible");

    }

    else if (gesture.state == UIGestureRecognizerStateBegan)

    {

        NSLog(@"began");

    }

    else if (gesture.state == UIGestureRecognizerStateChanged)

    {

        NSLog(@"changed");

    }

    else if (gesture.state == UIGestureRecognizerStateEnded)

    {

        NSLog(@"ended");

    }

}





1.手势识别实践



手势_第12张图片
如何解决手势冲突



手势_第13张图片
解决手势的优先级问题



手势_第14张图片
gestureB优先级高于gestureA


声明手势优先级可以解决swip和pan的冲突,让swip的优先级高于pan,这样快速向右滑动会触发swip,慢速会触发pan。



手势_第15张图片
手势_第16张图片
1.第一个gesture低于other  2.相反



手势_第17张图片
需要实现delegate


手势响应条件:单一手势如何控制手势精确识别


手势_第18张图片
判断是否从possible转变成recognized(可识别状态)



手势_第19张图片
判断一个手势是否可以进入possible状态,来解决这个问题。



手势_第20张图片


- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer*)gestureRecognizer

{

    if(gestureRecognizer ==_tap)

    {

        CGPointlocation = [gestureRecognizer locationInView:_superView];

        if (CGRectContainsPoint(_subView.frame, location))

        {

            return NO;//不触发手势

        }


        return YES;

    }


    return YES;

}


- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldReceiveTouch:(UITouch*)touch

{

    if(gestureRecognizer ==_tap)

    {

        if (touch.view != _superView && [touch.view isDescendantOfView:_superView])

        {

            returnNO;

        }

        returnYES;

    }


    return YES;

}



多手势同时响应


手势_第21张图片
定义我的手势是否可以与其他手势共存。


#import "GestureSimultaneousViewController.h" //边拉伸,边放大缩小

@interface GestureSimultaneousViewController()

{

    UIView*_view;


    UIPinchGestureRecognizer *_pinch;

    UIRotationGestureRecognizer *_rotation;

}

@end

@implementationGestureSimultaneousViewController

- (void)viewDidLoad

{

    [super viewDidLoad];


    self.view.backgroundColor = [UIColor whiteColor];

    self.edgesForExtendedLayout = UIRectEdgeNone;

    _view = [[UIView alloc] init];

    _view.backgroundColor = [UIColor orangeColor];

    _view.frame=CGRectMake(50, 50, 150, 150);

    [self.view addSubview:_view];


    _rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotate:)];//以弧度旋转

    _rotation.delegate = self;

    [self.view addGestureRecognizer:_rotation];


    _pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];//相对于触摸的缩放比例

    _pinch.delegate = self;

    [self.view addGestureRecognizer:_pinch];


}

- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer

{

    return YES;//允许多个手势共同触发

}

- (void)rotate:(UIRotationGestureRecognizer *)gesture

{

    if (gesture.state == UIGestureRecognizerStateChanged)

    {

        _view.transform = CGAffineTransformRotate(_view.transform, gesture.rotation);

        [gesturesetRotation:0];//回到原点

    }

}

- (void)pinch:(UIPinchGestureRecognizer *)gesture

{

    if (gesture.state == UIGestureRecognizerStateChanged)

    {

        _view.transform = CGAffineTransformScale(_view.transform, gesture.scale, gesture.scale);

        gesture.scale= 1;//回归缩放之前的状态

    }

}


自己手势和控件原生的手势发生冲突解决方案


手势_第22张图片
屏幕左侧进行滑动让当前的页面进行返回


手势_第23张图片
将edgPan的手势优先级高于系统手势的优先级,就可以解决(让自己写的手势响应事件了)
解决scrollview的pan手势和tableview横滑手势冲突问题

1.定义一个scrollview的子类,原因:scrollview的pan手势不允许更改

@interface TestScrollView : UIScrollView

@end

@implementation TestScrollView

- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldReceiveTouch:(UITouch*)touch

{

    if ([NSStringFromClass([touch.view class]) isEqualToString:@"UITableViewCellContentView"])

    {

        returnNO;//如果是tableview的cell的话不触发UIScrollview的pan手势

    }

    return YES;

}


@interface GestureSystemViewController()

{

    //demo5.1

    UIView*_testView;

    UIScreenEdgePanGestureRecognizer *_edgePan;


    //demo5.2

//    UIScrollView *_scrollView;

    TestScrollView*_scrollView;

    UITableView*_tableView;

}

@end

@implementationGestureSystemViewController

- (void)viewDidLoad

{

    [super viewDidLoad];


    self.view.backgroundColor = [UIColor whiteColor];

    self.edgesForExtendedLayout = UIRectEdgeNone;


    //demo5.1

    _testView = [[UIView alloc] init];

    _testView.backgroundColor = [UIColor orangeColor];

    _testView.frame=CGRectMake(50, 50, 150, 150);

    [self.view addSubview:_testView];


    _edgePan = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(edgePan:)];

    _edgePan.edges = UIRectEdgeLeft;

    [self.view addGestureRecognizer:_edgePan];


    [self.navigationController.interactivePopGestureRecognizer requireGestureRecognizerToFail:_edgePan];

    //demo5.2

//    _scrollView = [[UIScrollView alloc] init];

    _scrollView = [[TestScrollView alloc] init];

    _scrollView.backgroundColor = [UIColor lightGrayColor];

    _scrollView.frame=CGRectMake(50, 250, 300, 300);

    _scrollView.contentSize = CGSizeMake(1000, 300);

    [self.view addSubview:_scrollView];


    _tableView = [[UITableView alloc] init];

    _tableView.backgroundColor = [UIColor whiteColor];

    _tableView.delegate = self;

    _tableView.dataSource = self;

    _tableView.frame=CGRectMake(0, 10, 300, 280);

    [_scrollView addSubview:_tableView];

}

#pragma mark - pan

- (void)edgePan:(UIScreenEdgePanGestureRecognizer *)gesture

{

    if (gesture.state == UIGestureRecognizerStateChanged)

    {

        CGPointtranslatePoint = [gesturetranslationInView:self.view];

        _testView.center = CGPointMake(_testView.center.x + translatePoint.x, _testView.center.y);

        [gesturesetTranslation:CGPointZero inView:self.view];

    }

    else if (gesture.state == UIGestureRecognizerStateEnded)

    {

        _testView.frame=CGRectMake(50, 50, 150, 150);

    }

}

#pragma mark - tableview

- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section

{

    return10;

}

- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath

{

    NSString*identifier =@"cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];

    if(!cell) {

        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];

    }

    cell.textLabel.text = [NSString stringWithFormat:@"cell %zd", indexPath.row];

    returncell;

}

- (BOOL)tableView:(UITableView*)tableView canEditRowAtIndexPath:(NSIndexPath*)indexPath

{

    return YES;

}

- (void)tableView:(UITableView*)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath*)indexPath

{


}


自定义手势


手势_第24张图片
自定义手势实现步骤:(完成系统没有定义的手势操作,实现特殊的需求)


三指滑屏的demo,判断逻辑在touchbegin、touchmoved里面,除了这里面的其他的都是准备工作。


手势_第25张图片
需要上面这三个方法结构


#import "CustomGestureRecognizer.h" 自定义的手势,三指demo

#import

#import

@interfaceUITouch(BeginPoint)

@property(nonatomic,assign)CGPointtestCustomTouchBeginPoint;//保存手势开始滑动的时候的起点坐标

@end

@implementationUITouch(BeginPoint)

- (void)setTestCustomTouchBeginPoint:(CGPoint)testCustomTouchBeginPoint

{

    NSString*string =NSStringFromCGPoint(testCustomTouchBeginPoint);

    objc_setAssociatedObject(self, @"testCustomTouchBeginPoint", string, OBJC_ASSOCIATION_RETAIN_NONATOMIC);//将传入的point进行保存

}

- (CGPoint)testCustomTouchBeginPoint

{

    NSString *string = objc_getAssociatedObject(self, @"testCustomTouchBeginPoint");

    if(!string) {

        return CGPointZero;

    }

    CGPoint point = CGPointFromString(string); //将string转回point

    return point; 

}

@end

@implementationCustomGestureRecognizer

{

    id_testTarget;

    SEL_testAction;

}

- (instancetype)initWithTarget:(id)target action:(SEL)action

{

    self= [superinitWithTarget:targetaction:action];

    if(self)

    {

        _testTarget= target;

        _testAction= action;


    }

    return self;

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event

{


    for(UITouch*touchintouches) {

        touch.testCustomTouchBeginPoint = [touch locationInView:self.view];//记录每个touch在view当中的坐标

    }


    [supertouchesBegan:toucheswithEvent:event];

}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent*)event

{

    if(touches.count== 3)//检测是否是三指移动,然后出发响应的action

    {

        BOOLallTestPass =YES;

        for(UITouch*touch in touches)//遍历touchs,//x或者y移动都要超过100才能响应这个action  

        {

            CGPointcurrentPoint = [touchlocationInView:self.view];

            CGFloattouchMovedY = currentPoint.y- touch.testCustomTouchBeginPoint.y;

            CGFloattouchMovedX = currentPoint.x- touch.testCustomTouchBeginPoint.x;

            if(!(ABS(touchMovedX) > 100 ||ABS(touchMovedY) > 100))

            {

                allTestPass =NO;

                break;

            }

        }


        if(allTestPass)

        {

#pragma clang diagnostic push

#pragma clang diagnostic ignored"-Warc-performSelector-leaks"

            if ([_testTarget respondsToSelector:_testAction])

            {

                [_testTarget performSelector:_testAction withObject:self];

            }

#pragma clang diagnostic pop

        }    }

    [supertouchesMoved:toucheswithEvent:event];

}


#import "CustomGestureViewController.h" 

#import "CustomGestureRecognizer.h"

@implementationCustomGestureViewController //使用自定义的三指滑动手势

- (void)viewDidLoad

{

    [super viewDidLoad];


    self.view.backgroundColor = [UIColor whiteColor];

    self.edgesForExtendedLayout = UIRectEdgeNone;


    CustomGestureRecognizer *gesture = [[CustomGestureRecognizer alloc] initWithTarget:self action:@selector(customGesture:)];

    [self.view addGestureRecognizer:gesture];

}

- (void)customGesture:(CustomGestureRecognizer*)gesture

{

    [self alertMessage:@"custom gesture!!"];

}

- (void)alertMessage:(NSString*)message

{

    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];

    [alertaddAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];

    [self presentViewController:alert animated:YES completion:nil];

}



手势_第26张图片

你可能感兴趣的:(手势)