ios事件-触摸事件2(手势 和 pointInSide()、hitTest()、touchesBegan()、touchesMoved()、touchesEnded()的关系)

ios事件-触摸事件2(手势 和 pointInSide()、hitTest()、touchesBegan()、touchesMoved()、touchesEnded()的关系)ios事件-触摸事件2(手势和pointInSide()、hitTest()、touchesBegan()、touchesMoved()、touchesEnded()、touchesCancelled()的关系)先看效果图本文中,凡是看到xxx(),即表示xxx是一个函数或者方法!!!事件分为事件传递和事件响应,其中,事件响应又称事件处理。具体代码FindViewViewContr…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

ios事件-触摸事件2(手势 和 pointInSide()、hitTest()、touchesBegan()、touchesMoved()、touchesEnded()、touchesCancelled()的关系)

先看效果图

在这里插入图片描述

本文中,凡是看到xxx(),即表示xxx是一个函数或者方法!!!事件分为事件传递和事件响应,其中,事件响应又称事件处理。

具体代码

FindViewViewController的代码如下:

@interface GestureVC : UIViewController
@end
//--------分隔符,分隔.h文件和.m文件-------------
#import "GestureVC.h"
#import "CustomerGesture.h"
#import "GrayView.h"
#import "RedView.h"
#import "BlueView.h"
#import "YellowView.h"
/**
 1. 手势和pointInSide()以及hitTest()的关系:必须先通过pointInSide()和hitTest()找到的view(即处理事件的view),才能响应view的手势事件。
 2. 通过hitTest()、pointInSide()找到的view,那么view和它的superView的手势都能响应,但不会响应它的子view的手势。
 3. 手势的种类(tapGesture、panGesture、swipGesture)怎么分辨出来:手势的touch的4个方法来识别。所以如果你在你自定义的手势里面的重写的touchesBegan: withEvent:方法中不调用[super touchesBegan:touches withEvent:event];时,手势就无法识别,那么手势的监听方法(在本例中为panActiona方法)就不会被调用!
 4. 手势和view的touch事件的关系:delayTouchBegin、cancelTouchInView

 */
@implementation GestureVC

- (void)viewDidLoad {
    self.view.backgroundColor = UIColor.whiteColor;
    [self createGesture];
}

- (void)createGesture {
    RedView *redView = [[RedView alloc] initWithFrame:CGRectMake(100.f, 100.f, 100.f, 100.f)];
    [self.view addSubview:redView];
    
    CustomerGesture *gesture = [[CustomerGesture alloc] initWithTarget:self action:@selector(panActiona)];
   
    //默认情况下,如果手势识别出来了,会cancel掉view的touch事件,即调用view的touchesCancelled:withEvent:方法。
    
    [redView addGestureRecognizer:gesture];
}

- (void)panActiona {
    NSLog(@"%s", __func__);
}
@end

CustomerGesture的代码如下:

#import <UIKit/UIKit.h>
/**
CustomerGesture在本文底部的操作场景的讨论中,要么继承UIPanGestureRecognizer,要么继承UITapGestureRecognizer
*/
@interface CustomerGesture : UIPanGestureRecognizer
//@interface CustomerGesture : UITapGestureRecognizer
@end

//--------分隔符,分隔.h文件和.m文件-------------
@interface CustomerGesture () {
    int moveCount;
}
@end
@implementation CustomerGesture

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    moveCount = 0;
    NSLog(@"%s, moveCount = %d", __func__, moveCount);
    [super touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"%s, moveCount = %d", __func__, moveCount);
    moveCount++;
    [super touchesMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"%s, moveCount = %d", __func__, moveCount);
    [super touchesEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"%s, moveCount = %d", __func__, moveCount);
    [super touchesCancelled:touches withEvent:event];
}

@end

UIView+Color的代码如下:

@interface UIView (Color)
- (NSString *)bgColorString;
@end

//--------分隔符,分隔.h文件和.m文件-------------
@implementation UIView (Color)
- (NSString *)bgColorString {
    if (self.backgroundColor == [UIColor redColor]) {
        return @"redColorView";
    } else if (self.backgroundColor == UIColor.blueColor) {
        return @"blueColorView";
    } else if (self.backgroundColor == UIColor.yellowColor) {
        return @"yellowColorView";
    } else if (self.backgroundColor == UIColor.lightGrayColor) {
        return @"lightGrayColorView";
    }
    return nil;
}
@end

GrayView的代码如下:

@interface GrayView : UIView
@end

//--------分隔符,分隔.h文件和.m文件-------------
#import "UIView+Color.h"

@implementation GrayView
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = UIColor.lightGrayColor;
    }
    return self;
}
//返回的是 点击区域是否在该view的范围内。
//返回YES表示点击区域在当前view中,NO表示点击区域不在当前view中
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    NSLog(@"%@, %s", self.bgColorString, __func__);
    return [super pointInside:point withEvent:event];
}
//返回的是处理事件的view的实例。
//如果返回自己,表示处理事件的是当前view。返回nil表示当前view及其子view都不处理事件。
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    NSLog(@"%@, %s", self.bgColorString, __func__);
    return [super hitTest:point withEvent:event];
}

//scrollView 系统会重写它的super touch:导致不能往上传递,
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"%@, %s", self.bgColorString, __func__);
    [super touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"%@, %s", self.bgColorString, __func__);
    [super touchesMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"%@, %s", self.bgColorString, __func__);
    [super touchesEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"%@, %s", self.bgColorString, __func__);
    [super touchesCancelled:touches withEvent:event];
}
@end

BlueView、RedView和YellowView的代码和上面的GrayView的代码相同,只是类名不一样,这里就不贴出来了。

操作场景

  1. CustomerGesture继承UITapGestureRecognizer, 点击一下红色按钮:,输出结果如下:
redColorView, -[RedView hitTest:withEvent:]
redColorView, -[RedView pointInside:withEvent:]
-[CustomerGesture touchesBegan:withEvent:], moveCount = 0
redColorView, -[RedView touchesBegan:withEvent:]
-[CustomerGesture touchesEnded:withEvent:], moveCount = 0//此时CustomerGesture识别出是点击手势了,就会调用[RedView touchesCancelled:withEvent:]
-[GestureVC panActiona]
redColorView, -[RedView touchesCancelled:withEvent:]
  • 事件传递:通过RedView的hitTest()和pointInSide()的调用可知是处理事件的是RedView。
  • 事件响应:touchesBegan()的调用顺序是:CustomerGesture->RedView。 当手指离开屏幕时,CustomerGesture的touchesEnded()会被调用。因为这时已经识别出手势为UITapGestureRecognizer类型,所以系统就会调用手势的监听方法(GestureVC类的panActiona方法),接着调用[RedView touchesCancelled:withEvent:],所以RedView的touchesEnded:withEvent:方法不会被调用。
  1. CustomerGesture继承UITapGestureRecognizer, 在红色按钮的区域内用手指滑动一下,输出结果如下:
redColorView, -[RedView hitTest:withEvent:]
redColorView, -[RedView pointInside:withEvent:]
-[CustomerGesture touchesBegan:withEvent:], moveCount = 0
redColorView, -[RedView touchesBegan:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 0
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 1
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 2
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 3
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 4
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 5
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 6
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 7
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 8
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 9
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 10
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 11
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 12
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 13 //识别出不是点击手势了,所以[CustomerGesture touchesMoved:withEvent:]就不会再被调用了。
redColorView, -[RedView touchesMoved:withEvent:]
redColorView, -[RedView touchesMoved:withEvent:]
redColorView, -[RedView touchesMoved:withEvent:]
redColorView, -[RedView touchesMoved:withEvent:]
redColorView, -[RedView touchesMoved:withEvent:]
redColorView, -[RedView touchesMoved:withEvent:]
redColorView, -[RedView touchesEnded:withEvent:]
  • 事件传递::通过RedView的hitTest()和pointInSide()的调用可知是处理事件的是RedView。
  • 事件响应:touchesBegan()的调用顺序是:CustomerGesture->RedView。 touchesMoved()的调用顺序是:CustomerGesture->RedView。当系统识别出不是点击手势(即不是UITapGestureRecognizer)了,所以[CustomerGesture touchesMoved:withEvent:]就不会再被调用了,而此时RedView的touchesMoved:withEvent:方法一直被调用(前提是手指还在RedView上滑动)。 当手指离开屏幕时,RedView的touchesEnded()会被调用。
  1. CustomerGesture继承UIPanGestureRecognizer, 点击一下红色按钮,输出结果如下:
 redColorView, -[RedView hitTest:withEvent:]
redColorView, -[RedView pointInside:withEvent:]
-[CustomerGesture touchesBegan:withEvent:]
redColorView, -[RedView touchesBegan:withEvent:]
-[CustomerGesture touchesEnded:withEvent:]
redColorView, -[RedView touchesEnded:withEvent:]
  • 事件传递::通过RedView的hitTest()和pointInSide()的调用可知是处理事件的是RedView。
  • 事件响应:touchesBegan()的调用顺序是:CustomerGesture->RedView。当手指离开屏幕时, touchesEnded()的调用顺序是:CustomerGesture->RedView。当系统识别出不是滑动手势(即不是UIPanGestureRecognizer)了,所以系统不会调用RedView的touchesCancelled:withEvent:方法,所以RedView的touchesEnded:withEvent:方法会被调用。
  1. CustomerGesture继承UIPanGestureRecognizer, 在红色按钮的区域内用手指滑动一下,输出结果如下:
 redColorView, -[RedView hitTest:withEvent:]
redColorView, -[RedView pointInside:withEvent:]
-[CustomerGesture touchesBegan:withEvent:], moveCount = 0
redColorView, -[RedView touchesBegan:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 0
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 1
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 2
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 3
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 4
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 5
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 6
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 7
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 8
redColorView, -[RedView touchesMoved:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 9 //此时CustomerGesture识别出是滑动手势了,就会调用[RedView touchesCancelled:withEvent:]
-[GestureVC panActiona]
redColorView, -[RedView touchesCancelled:withEvent:]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 10
-[GestureVC panActiona]
-[GestureVC panActiona]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 11
-[GestureVC panActiona]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 12
-[GestureVC panActiona]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 13
-[GestureVC panActiona]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 14
-[GestureVC panActiona]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 15
-[GestureVC panActiona]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 16
-[GestureVC panActiona]
-[CustomerGesture touchesMoved:withEvent:], moveCount = 17
-[GestureVC panActiona]
-[CustomerGesture touchesEnded:withEvent:], moveCount = 18
-[GestureVC panActiona]
  • 事件传递::通过RedView的hitTest()和pointInSide()的调用可知是处理事件的是RedView。
  • 事件响应:touchesBegan()的调用顺序是:CustomerGesture->RedView。当手指在RedView上滑动时, touchesMoved()的调用顺序是:CustomerGesture->RedView。当系统识别出是滑动手势(即是UIPanGestureRecognizer)了,所以系统会调用RedView的touchesCancelled:withEvent:方法,然后调用手势的监听方法(GestureVC类的panActiona方法)。所以在后面的触摸事件中,RedView的touchesEnded:withEvent:方法不再会被调用,而是调用CustomerGesture的touchesMoved:withEvent:方法和GestureVC的panActiona方法。当手指离开屏幕时,CustomerGesture 的touchesEnded:withEvent:方法和GestureVC的panActiona方法会被调用。
  1. CustomerGesture继承UIPanGestureRecognizer, 在GestureVC.m中的createGesture()中添加gesture.cancelsTouchesInView = NO;,此时GestureVC.m的代码如下:
@implementation GestureVC
- (void)viewDidLoad {
    self.view.backgroundColor = UIColor.whiteColor;
    [self createGesture];
}

- (void)createGesture {
    RedView *redView = [[RedView alloc] initWithFrame:CGRectMake(100.f, 100.f, 100.f, 100.f)];
    [self.view addSubview:redView];
    
    CustomerGesture *gesture = [[CustomerGesture alloc] initWithTarget:self action:@selector(panActiona)];
    
    //默认情况下,如果手势识别出来了,会cancel掉view的touch事件,即调用view的touchesCancelled:withEvent:方法。
    //默认为YES。NO表示手势识别出来,不cancel掉view的touch方法的回调
    gesture.cancelsTouchesInView = NO; //只是添加了这一行代码!!!!!!!!!!

    [redView addGestureRecognizer:gesture];
}
- (void)panActiona {
    NSLog(@"%s", __func__);
}
@end

此时在红色按钮的区域内用手指滑动一下,输出结果如下:

2019-08-30 15:08:03.245348+0800 E03事件层次分析[12668:8488735] redColorView, -[RedView hitTest:withEvent:]
2019-08-30 15:08:03.245486+0800 E03事件层次分析[12668:8488735] redColorView, -[RedView pointInside:withEvent:]
2019-08-30 15:08:03.246028+0800 E03事件层次分析[12668:8488735] -[CustomerGesture touchesBegan:withEvent:], moveCount = 0
2019-08-30 15:08:03.246345+0800 E03事件层次分析[12668:8488735] redColorView, -[RedView touchesBegan:withEvent:]
2019-08-30 15:08:03.289045+0800 E03事件层次分析[12668:8488735] -[CustomerGesture touchesMoved:withEvent:], moveCount = 0
2019-08-30 15:08:03.289256+0800 E03事件层次分析[12668:8488735] redColorView, -[RedView touchesMoved:withEvent:]
2019-08-30 15:08:03.327937+0800 E03事件层次分析[12668:8488735] -[CustomerGesture touchesMoved:withEvent:], moveCount = 1
2019-08-30 15:08:03.328154+0800 E03事件层次分析[12668:8488735] redColorView, -[RedView touchesMoved:withEvent:]
2019-08-30 15:08:03.351235+0800 E03事件层次分析[12668:8488735] -[CustomerGesture touchesMoved:withEvent:], moveCount = 2
2019-08-30 15:08:03.351494+0800 E03事件层次分析[12668:8488735] -[GestureVC panActiona]
2019-08-30 15:08:03.351644+0800 E03事件层次分析[12668:8488735] redColorView, -[RedView touchesMoved:withEvent:]
2019-08-30 15:08:03.372921+0800 E03事件层次分析[12668:8488735] -[CustomerGesture touchesMoved:withEvent:], moveCount = 3
2019-08-30 15:08:03.373281+0800 E03事件层次分析[12668:8488735] -[GestureVC panActiona]
2019-08-30 15:08:03.373476+0800 E03事件层次分析[12668:8488735] -[GestureVC panActiona]
2019-08-30 15:08:03.373616+0800 E03事件层次分析[12668:8488735] redColorView, -[RedView touchesMoved:withEvent:]
2019-08-30 15:08:03.405831+0800 E03事件层次分析[12668:8488735] -[CustomerGesture touchesMoved:withEvent:], moveCount = 4
2019-08-30 15:08:03.406057+0800 E03事件层次分析[12668:8488735] -[GestureVC panActiona]
2019-08-30 15:08:03.406194+0800 E03事件层次分析[12668:8488735] redColorView, -[RedView touchesMoved:withEvent:]
2019-08-30 15:08:03.507371+0800 E03事件层次分析[12668:8488735] -[CustomerGesture touchesEnded:withEvent:], moveCount = 5
2019-08-30 15:08:03.507584+0800 E03事件层次分析[12668:8488735] -[GestureVC panActiona]
2019-08-30 15:08:03.507818+0800 E03事件层次分析[12668:8488735] redColorView, -[RedView touchesEnded:withEvent:]

从上面的结果可以看出,当系统虽然识别出是滑动手势(即是UIPanGestureRecognizer)了,但不会调用RedView的touchesCancelled:withEvent:方法,然后调用手势的监听方法(GestureVC类的panActiona方法),接着调用RedView的 touchesMoved:withEvent:方法,直到手指离开屏幕。

  1. CustomerGesture继承UIPanGestureRecognizer, 在GestureVC.m中的createGesture()中添加gesture.delaysTouchesBegan = YES;,此时GestureVC.m的代码如下:
@implementation GestureVC
- (void)viewDidLoad {
    self.view.backgroundColor = UIColor.whiteColor;
    [self createGesture];
}

- (void)createGesture {
    RedView *redView = [[RedView alloc] initWithFrame:CGRectMake(100.f, 100.f, 100.f, 100.f)];
    [self.view addSubview:redView];

    CustomerGesture *gesture = [[CustomerGesture alloc] initWithTarget:self action:@selector(panActiona)];
    
    //默认为NO。如果为YES,无论什么手势(比如UITapGestureRecognizer或者UIPanGestureRecognizer),就阻止view的touchesBegan方法的调用(识别)
    gesture.delaysTouchesBegan = YES; //只有这一行代码被添加!!!!!!!
    
    [redView addGestureRecognizer:gesture];
}

- (void)panActiona {
    NSLog(@"%s", __func__);
}
@end

此时在红色按钮的区域内用手指滑动一下,输出结果如下:

2019-08-31 12:31:42.318117+0800 E03事件层次分析[26416:9622148] redColorView, -[RedView hitTest:withEvent:]
2019-08-31 12:31:42.318357+0800 E03事件层次分析[26416:9622148] redColorView, -[RedView pointInside:withEvent:]
2019-08-31 12:31:42.319321+0800 E03事件层次分析[26416:9622148] -[CustomerGesture touchesBegan:withEvent:], moveCount = 0
2019-08-31 12:31:42.362970+0800 E03事件层次分析[26416:9622148] -[CustomerGesture touchesMoved:withEvent:], moveCount = 0
2019-08-31 12:31:42.385229+0800 E03事件层次分析[26416:9622148] -[CustomerGesture touchesMoved:withEvent:], moveCount = 1
2019-08-31 12:31:42.407373+0800 E03事件层次分析[26416:9622148] -[CustomerGesture touchesMoved:withEvent:], moveCount = 2
2019-08-31 12:31:42.407749+0800 E03事件层次分析[26416:9622148] -[GestureVC panActiona]
2019-08-31 12:31:42.429652+0800 E03事件层次分析[26416:9622148] -[CustomerGesture touchesMoved:withEvent:], moveCount = 3
2019-08-31 12:31:42.429888+0800 E03事件层次分析[26416:9622148] -[GestureVC panActiona]
2019-08-31 12:31:42.430015+0800 E03事件层次分析[26416:9622148] -[GestureVC panActiona]
2019-08-31 12:31:42.452773+0800 E03事件层次分析[26416:9622148] -[CustomerGesture touchesMoved:withEvent:], moveCount = 4
2019-08-31 12:31:42.453046+0800 E03事件层次分析[26416:9622148] -[GestureVC panActiona]
2019-08-31 12:31:42.474992+0800 E03事件层次分析[26416:9622148] -[CustomerGesture touchesMoved:withEvent:], moveCount = 5
2019-08-31 12:31:42.475262+0800 E03事件层次分析[26416:9622148] -[GestureVC panActiona]
2019-08-31 12:31:42.541643+0800 E03事件层次分析[26416:9622148] -[CustomerGesture touchesMoved:withEvent:], moveCount = 6
2019-08-31 12:31:42.541836+0800 E03事件层次分析[26416:9622148] -[GestureVC panActiona]
2019-08-31 12:31:42.576170+0800 E03事件层次分析[26416:9622148] -[CustomerGesture touchesEnded:withEvent:], moveCount = 7
2019-08-31 12:31:42.576434+0800 E03事件层次分析[26416:9622148] -[GestureVC panActiona]

从上面的结果可以看出,当系统虽然识别出是滑动手势(即是UIPanGestureRecognizer)了,就会调用手势的监听方法(GestureVC类的panActiona方法)。在整个事件序列中(一个事件序列是:手机触摸屏幕,接着在屏幕滑动,最后手指离开屏幕),RedView的touches开头的4个方法都不会被调用!

  1. CustomerGesture继承UIPanGestureRecognizer, 在GestureVC.m中的createGesture()中同时添加gesture.delaysTouchesBegan = YES;gesture.cancelsTouchesInView = NO;,此时GestureVC.m的代码如下:
@implementation GestureVC
- (void)viewDidLoad {
    self.view.backgroundColor = UIColor.whiteColor;
    [self createGesture];
}

- (void)createGesture {
    RedView *redView = [[RedView alloc] initWithFrame:CGRectMake(100.f, 100.f, 100.f, 100.f)];
    [self.view addSubview:redView];
    
    CustomerGesture *gesture = [[CustomerGesture alloc] initWithTarget:self action:@selector(panActiona)];
    
    //默认情况下,如果手势识别出来了,会cancel掉view的touch事件,即调用view的touchesCancelled:withEvent:方法。
    
    //默认为NO。如果为YES,无论什么手势(比如UITapGestureRecognizer或者UIPanGestureRecognizer),就阻止view的touchesBegan方法的调用(识别)
    gesture.delaysTouchesBegan = YES;
    //默认为YES。NO表示手势识别出来,不cancel掉view的touch方法的回调
    gesture.cancelsTouchesInView = NO;
    
    [redView addGestureRecognizer:gesture];
}

- (void)panActiona {
    NSLog(@"%s", __func__);
}
@end

此时在红色按钮的区域内用手指滑动一下,输出结果如下:

2019-08-31 12:35:35.657777+0800 E03事件层次分析[26481:9629016] redColorView, -[RedView hitTest:withEvent:]
2019-08-31 12:35:35.657978+0800 E03事件层次分析[26481:9629016] redColorView, -[RedView pointInside:withEvent:]
2019-08-31 12:35:35.658789+0800 E03事件层次分析[26481:9629016] -[CustomerGesture touchesBegan:withEvent:], moveCount = 0
2019-08-31 12:35:35.702652+0800 E03事件层次分析[26481:9629016] -[CustomerGesture touchesMoved:withEvent:], moveCount = 0
2019-08-31 12:35:35.724521+0800 E03事件层次分析[26481:9629016] -[CustomerGesture touchesMoved:withEvent:], moveCount = 1
2019-08-31 12:35:35.747421+0800 E03事件层次分析[26481:9629016] -[CustomerGesture touchesMoved:withEvent:], moveCount = 2
2019-08-31 12:35:35.748178+0800 E03事件层次分析[26481:9629016] -[GestureVC panActiona]
2019-08-31 12:35:35.748529+0800 E03事件层次分析[26481:9629016] redColorView, -[RedView touchesMoved:withEvent:]
2019-08-31 12:35:35.770069+0800 E03事件层次分析[26481:9629016] -[CustomerGesture touchesMoved:withEvent:], moveCount = 3
2019-08-31 12:35:35.770455+0800 E03事件层次分析[26481:9629016] -[GestureVC panActiona]
2019-08-31 12:35:35.770726+0800 E03事件层次分析[26481:9629016] -[GestureVC panActiona]
2019-08-31 12:35:35.771042+0800 E03事件层次分析[26481:9629016] redColorView, -[RedView touchesMoved:withEvent:]
2019-08-31 12:35:35.791819+0800 E03事件层次分析[26481:9629016] -[CustomerGesture touchesMoved:withEvent:], moveCount = 4
2019-08-31 12:35:35.792046+0800 E03事件层次分析[26481:9629016] -[GestureVC panActiona]
2019-08-31 12:35:35.792181+0800 E03事件层次分析[26481:9629016] redColorView, -[RedView touchesMoved:withEvent:]
2019-08-31 12:35:35.815099+0800 E03事件层次分析[26481:9629016] -[CustomerGesture touchesMoved:withEvent:], moveCount = 5
2019-08-31 12:35:35.815475+0800 E03事件层次分析[26481:9629016] -[GestureVC panActiona]
2019-08-31 12:35:35.815723+0800 E03事件层次分析[26481:9629016] redColorView, -[RedView touchesMoved:withEvent:]
2019-08-31 12:35:35.896018+0800 E03事件层次分析[26481:9629016] -[CustomerGesture touchesEnded:withEvent:], moveCount = 6
2019-08-31 12:35:35.896272+0800 E03事件层次分析[26481:9629016] -[GestureVC panActiona]
2019-08-31 12:35:35.896564+0800 E03事件层次分析[26481:9629016] redColorView, -[RedView touchesEnded:withEvent:]

从上面的结果可以看出,当系统虽然识别出是滑动手势(即是UIPanGestureRecognizer)了,就会调用手势的监听方法(GestureVC类的panActiona方法),因为GestureVC.m中添加了gesture.cancelsTouchesInView = NO;,即告诉系统说手势识别出来后,不要cancel掉view的touch方法的回调,所以RedView的touchesMoved:withEvent:方法和touchesEnded:withEvent:方法还是会被调用。

写的有些乱,如果你能看到这里,那你挺厉害的。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/164169.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(2)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号