iOS开发中的手势体系——UIGestureRecognizer分析及其子类的使用(一)

简介: iOS开发中的手势体系——UIGestureRecognizer分析及其子类的使用

iOS开发中的手势体系——UIGestureRecognizer分析及其子类的使用


一、引言


       在iOS系统中,手势是进行用户交互的重要方式,通过UIGestureRecognizer类,我们可以轻松的创建出各种手势应用于app中。关于UIGestureRecognizer类,是对iOS中的事件传递机制面向应用的封装,将手势消息的传递抽象为了对象。有关消息传递的一些讨论,在前面的博客中有提到:


iOS事件响应控制:http://my.oschina.net/u/2340880/blog/396161


二、手势的抽象类——UIGestureRecognizer


       UIGestureRecognizer将一些和手势操作相关的方法抽象了出来,但它本身并不实现什么手势,因此,在开发中,我们一般不会直接使用UIGestureRecognizer的对象,而是通过其子类进行实例化,iOS系统给我们提供了许多用于我们实例的子类,这些我们后面再说,我们先来看一下,UIGestureRecognizer中抽象出了哪些方法。


1、统一的初始化方法


       UIGestureRecognizer类为其子类准备好了一个统一的初始化方法,无论什么样的手势动作,其执行的结果都是一样的:触发一个方法,可以使用下面的方法进行统一的初始化:


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

当然,如果我们使用alloc-init的方式,也是可以的,下面的方法可以为手势添加触发的selector:


- (void)addTarget:(id)target action:(SEL)action;

与之相对应的,我们也可以将一个selector从其手势对象上移除:


- (void)removeTarget:(nullable id)target action:(nullable SEL)action;

上面两个方法是十分有意思的,因为addTarget方式的存在,iOS系统允许一个手势对象可以添加多个selector触发方法,并且触发的时候,所有添加的selector都会被执行,我们以点击手势示例如下:


- (void)viewDidLoad {

   [super viewDidLoad];

   // Do any additional setup after loading the view, typically from a nib.

    UITapGestureRecognizer * ges = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(click:)];

   [ges addTarget:self action:@selector(haha)];

    [self.view addGestureRecognizer:ges];

}

-(void)click:(UIGestureRecognizer *)ges{

 

   NSLog(@"第一个手势的触发方法");

 

}

-(void)haha{

   NSLog(@"haha");

}

运行后点击屏幕,打印如下,说明两个方法都触发了:


image.png


2、手势状态


       UIgestureRecognizer类中有如下一个属性,里面枚举了一些手势的当前状态:


@property(nonatomic,readonly) UIGestureRecognizerState state;

枚举值如下:


typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {

   UIGestureRecognizerStatePossible,   // 默认的状态,这个时候的手势并没有具体的情形状态

   UIGestureRecognizerStateBegan,      // 手势开始被识别的状态

   UIGestureRecognizerStateChanged,    // 手势识别发生改变的状态

   UIGestureRecognizerStateEnded,      // 手势识别结束,将会执行触发的方法

   UIGestureRecognizerStateCancelled,  // 手势识别取消

   UIGestureRecognizerStateFailed,     // 识别失败,方法将不会被调用

   UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded

};

3、常用属性和方法


//设置代理,具体的协议后面会说

@property(nullable,nonatomic,weak) id <UIGestureRecognizerDelegate> delegate;

//设置手势是否有效

@property(nonatomic, getter=isEnabled) BOOL enabled;

//获取手势所在的view

@property(nullable, nonatomic,readonly) UIView *view;

//获取触发触摸的点

- (CGPoint)locationInView:(nullable UIView*)view;

//设置触摸点数

- (NSUInteger)numberOfTouches;

//获取某一个触摸点的触摸位置

- (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(nullable UIView*)view;

下面的几个BOOL值的属性,对于手势触发的控制也十分重要:


(1)


@property(nonatomic) BOOL cancelsTouchesInView;

上面的属性默认为YES,当这个属性设置为YES时,如果识别到了手势,系统将会发送touchesCancelled:withEvent:消息在其时间传递链上,终止触摸事件的传递,设置为NO,则不会终止事件的传递,举个例子来说,可能会更加清楚一些如下:


- (void)viewDidLoad {

   [super viewDidLoad];

    UIPanGestureRecognizer * ges = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(click:)];;

   [self.view addGestureRecognizer:ges];

   ges.cancelsTouchesInView=NO;

}

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

   NSLog(@"123");

}

-(void)click:(UIGestureRecognizer *)ges{

   NSLog(@"第一个手势的触发方法");

}

上面我们使用了拖拽手势和touchesMoved两个触发方式,当我们把cancelTouchesInView设置为NO时,在屏幕上滑动,会发现两种方式都在触发,打印如下:


image.png


如果我们将cancelTouchesInView改为YES,当手势触发时,将取消触摸消息的触发:

image.png



(2)


@property(nonatomic) BOOL delaysTouchesBegan;

通过上面的例子,我们知道,在一个手势触发之前,是会一并发消息给事件传递链的,delaysTouchesBgan属性用于控制这个消息的传递时机,默认这个属性为NO,此时在触摸开始的时候,就会发消息给事件传递链,如果我们设置为YES,在触摸没有被识别失败前,都不会给事件传递链发送消息。


(3)


@property(nonatomic) BOOL delaysTouchesEnded;

这个属性设置手势识别结束后,是立刻发送touchesEnded消息到事件传递链或者等待一个很短的时间后,如果没有接收到新的手势识别任务,再发送。


4、手势间的互斥处理


       有一点需要注意,同一个View上是可以添加多个手势对象的,默认这个手势是互斥的,一个手势触发了就会默认屏蔽其他相似的手势动作,例如:


- (void)viewDidLoad {

   [super viewDidLoad];

   // Do any additional setup after loading the view, typically from a nib.

    UITapGestureRecognizer * ges = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(click:)];;

 

   //view.backgroundColor = [UIColor redColor];

 

   //ges.delegate=self;

   [self.view addGestureRecognizer:ges];

 

   UITapGestureRecognizer * ges2 = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(click1:)];

//    ges2.delegate=self;

       [self.view addGestureRecognizer:ges2];

}



-(void)click:(UIGestureRecognizer *)ges{

 

   NSLog(@"第一个手势的触发方法");

 

}

-(void)click1:(UIGestureRecognizer *)ges1{

   NSLog(@"第二个手势的触发方法");

 

 

}

我们添加的两个手势都是单机手势,会产生冲突,触发是很随机的,如果我们想设置一下当手势互斥时要优先触发的手势,可以使用如下的方法:


- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;

这个方法中第一个参数是需要时效的手势,第二个是生效的手势。


目录
相关文章
|
13天前
|
Java Android开发 Swift
安卓与iOS开发对比:平台选择对项目成功的影响
【10月更文挑战第4天】在移动应用开发的世界中,选择合适的平台是至关重要的。本文将深入探讨安卓和iOS两大主流平台的开发环境、用户基础、市场份额和开发成本等方面的差异,并分析这些差异如何影响项目的最终成果。通过比较这两个平台的优势与挑战,开发者可以更好地决定哪个平台更适合他们的项目需求。
54 1
|
20天前
|
设计模式 安全 Swift
探索iOS开发:打造你的第一个天气应用
【9月更文挑战第36天】在这篇文章中,我们将一起踏上iOS开发的旅程,从零开始构建一个简单的天气应用。文章将通过通俗易懂的语言,引导你理解iOS开发的基本概念,掌握Swift语言的核心语法,并逐步实现一个具有实际功能的天气应用。我们将遵循“学中做,做中学”的原则,让理论知识和实践操作紧密结合,确保学习过程既高效又有趣。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你打开一扇通往iOS开发世界的大门。
|
21天前
|
搜索推荐 IDE API
打造个性化天气应用:iOS开发之旅
【9月更文挑战第35天】在这篇文章中,我们将一起踏上iOS开发的旅程,通过创建一个个性化的天气应用来探索Swift编程语言的魅力和iOS平台的强大功能。无论你是编程新手还是希望扩展你的技能集,这个项目都将为你提供实战经验,帮助你理解从构思到实现一个应用的全过程。让我们开始吧,构建你自己的天气应用,探索更多可能!
44 1
|
14天前
|
移动开发 前端开发 Swift
iOS 最好的应用程序开发编程语言竟然是这7种
iOS 最好的应用程序开发编程语言竟然是这7种
49 8
|
12天前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异:从代码到用户体验
【10月更文挑战第5天】在移动应用开发的广阔天地中,安卓和iOS两大平台各占半壁江山。它们在技术架构、开发环境及用户体验上有着根本的不同。本文通过比较这两种平台的开发过程,揭示背后的设计理念和技术选择如何影响最终产品。我们将深入探讨各自平台的代码示例,理解开发者面临的挑战,以及这些差异如何塑造用户的日常体验。
|
16天前
|
安全 Swift iOS开发
探索iOS开发中的Swift语言之美
在数字时代的浪潮中,移动应用已成为日常生活的延伸。本文将深入探讨iOS平台上的Swift编程语言,揭示其背后的设计哲学、语法特性以及如何利用Swift进行高效开发。我们将通过实际代码示例,展示Swift语言的强大功能和优雅简洁的编程风格,引导读者理解并运用Swift解决实际问题。
|
26天前
|
开发框架 移动开发 Android开发
安卓与iOS开发中的跨平台解决方案:Flutter入门
【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
65 7
|
9天前
|
开发工具 Android开发 Swift
安卓与iOS开发环境的差异性分析
【10月更文挑战第8天】 本文旨在探讨Android和iOS两大移动操作系统在开发环境上的不同,包括开发语言、工具、平台特性等方面。通过对这些差异性的分析,帮助开发者更好地理解两大平台,以便在项目开发中做出更合适的技术选择。
|
29天前
|
IDE Android开发 iOS开发
探索Android与iOS开发的差异:平台选择对项目成功的影响
【9月更文挑战第27天】在移动应用开发的世界中,Android和iOS是两个主要的操作系统平台。每个系统都有其独特的开发环境、工具和用户群体。本文将深入探讨这两个平台的关键差异点,并分析这些差异如何影响应用的性能、用户体验和最终的市场表现。通过对比分析,我们将揭示选择正确的开发平台对于确保项目成功的重要作用。
|
1月前
|
开发框架 数据可视化 Java
iOS开发-SwiftUI简介
iOS开发-SwiftUI简介