一、响应者链

以UIResponder作为超类的任何类都是响应者。UIView和UIControl是UIReponder的子类,因此所有视图和所有控件都是响应者。

  • 初始相应器
    事件首先会传递给UIApplication对象,接下来会传递给应用程序的UIWindow,UIWindow会选择一个初始相应器来处理事件。初始响应器会选择下面的方式选择1、对于触摸事件,UIWindow会确定用户触摸的视图,然后将事件交给注册了这个视图的手势识别器或则注册视图层级更高的手势识别器。只要存在能处理事件的识别器,就不会再继续找了。如果没有的话,被触摸视图就是初始相应器,事件也会传递给它。
    2、对于用户摇晃设备产生的或者是来自远程遥控设备事件,将会传递给第一响应器
    如果初始响应器不处理时间,它会将事件传递给它的父视图(如果存在的话),或者传递给视图控制器(如果此视图是视图控制器的视图)。如果视图控制器不处理事件,它将沿着响应器链的层级继续传给父视图控制器(如果存在的话)。
    如果在整个视图层级中都没与能处理事件的视图或控制器,事件就会被传递给应用程序的窗口。如果窗口不能处理事件,而应用委托是UIResponder的子类,UIApplication对象就会将其传递给应用程序委托。最后,如果应用委托不是UIResponder的子类,或者不处理这个事件,那么这个事件将会被丢弃。

4个手势通知方法

#pragma mark - Touch Event Methods
// 用户第一次触摸屏幕时被调用
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{ } // 当发生某些事件(如来电呼叫)导致手势中断时被调用
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{ } // 当用户手指离开屏幕时被调用
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{ } // 当用户手指移动时触发
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{ }

二、检测扫描事件

1、手动检测

//
// ViewController.m
// Swipes
//
// Created by Jierism on 16/8/4.
// Copyright © 2016年 Jierism. All rights reserved.
// #import "ViewController.h"
// 设置检测范围
static CGFloat const kMinimmGestureLength = ;
static CGFloat const kMaximmVariance = ; @interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (nonatomic) CGPoint gestureStartPoint;
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
self.gestureStartPoint = [touch locationInView:self.view];
} - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint currentPosition = [touch locationInView:self.view];
// 返回一个float的绝对值
CGFloat deltaX = fabsf(self.gestureStartPoint.x - currentPosition.x);
CGFloat deltaY = fabsf(self.gestureStartPoint.y - currentPosition.y); // 获得两个增量后,判断用户在两个方向上移动过的距离,检测用户是否在一个方向上移动得足够远但在另一个方向移动得不够来形成轻扫动作
if (deltaX >= kMinimmGestureLength && deltaY <= kMaximmVariance) {
self.label.text = @"Horizontal swipe detected";
// 2s后擦除文本
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)( * NSEC_PER_SEC)),
dispatch_get_main_queue(),
^{
self.label.text = @"";
});
}else if (deltaY >= kMinimmGestureLength && deltaX <= kMaximmVariance){
self.label.text = @"Vertical swipe detected";
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)( * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.label.text = @"";
});
}
} @end

2、识别器检测

//
// ViewController.m
// Swipes
//
// Created by Jierism on 16/8/4.
// Copyright © 2016年 Jierism. All rights reserved.
// #import "ViewController.h" @interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (nonatomic) CGPoint gestureStartPoint;
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//创建两个手势识别器
// 1、水平方向识别器
UISwipeGestureRecognizer *horizontal = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(reportHorizontalSwipe:)]; horizontal.direction = UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:horizontal]; // 2、垂直方向识别器
UISwipeGestureRecognizer *vertical = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(reportVerticalSwipe:)];
vertical.direction = UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown;
[self.view addGestureRecognizer:vertical];
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} - (void)reportHorizontalSwipe:(UIGestureRecognizer *)recognizer
{ self.label.text = @"Horizontal swipe detected";
// 2s后擦除文本
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)( * NSEC_PER_SEC)),
dispatch_get_main_queue(),
^{
self.label.text = @"";
});
} - (void)reportVerticalSwipe:(UIGestureRecognizer *)recognizer
{
self.label.text = @"Vertical swipe detected";
// 2s后擦除文本
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)( * NSEC_PER_SEC)),
dispatch_get_main_queue(),
^{
self.label.text = @"";
});
} @end

三、实现多指轻扫

//
// ViewController.m
// Swipes
//
// Created by Jierism on 16/8/4.
// Copyright © 2016年 Jierism. All rights reserved.
// #import "ViewController.h" @interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (nonatomic) CGPoint gestureStartPoint;
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. for (NSUInteger touchCount = ; touchCount <= ; touchCount++) {
//创建两个手势识别器
// 1、水平方向识别器
UISwipeGestureRecognizer *horizontal = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(reportHorizontalSwipe:)]; horizontal.direction = UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:horizontal]; // 2、垂直方向识别器
UISwipeGestureRecognizer *vertical = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(reportVerticalSwipe:)];
vertical.direction = UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown;
[self.view addGestureRecognizer:vertical];
} } - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} - (NSString *)descriptionForTouchCount:(NSUInteger)touchCount
{
switch (touchCount) {
case :
return @"Single";
case :
return @"Double";
case :
return @"Triple";
case :
return @"Quadruple";
case :
return @"Quintuple"; default:
return @"";
}
} - (void)reportHorizontalSwipe:(UIGestureRecognizer *)recognizer
{ self.label.text = [NSString stringWithFormat:@"%@ Horizontal swipe detected",[self descriptionForTouchCount:[recognizer numberOfTouches]]];
// 2s后擦除文本
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)( * NSEC_PER_SEC)),
dispatch_get_main_queue(),
^{
self.label.text = @"";
});
} - (void)reportVerticalSwipe:(UIGestureRecognizer *)recognizer
{
self.label.text = [NSString stringWithFormat:@"%@ Vertical swipe detected",[self descriptionForTouchCount:[recognizer numberOfTouches]]];
// 2s后擦除文本
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)( * NSEC_PER_SEC)),
dispatch_get_main_queue(),
^{
self.label.text = @"";
});
} @end

四、检测多次轻点

//
// ViewController.m
// TapTaps
//
// Created by Jierism on 16/8/4.
// Copyright © 2016年 Jierism. All rights reserved.
// #import "ViewController.h" @interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *singleLabel;
@property (weak, nonatomic) IBOutlet UILabel *doubleLabel;
@property (weak, nonatomic) IBOutlet UILabel *tripleLabel;
@property (weak, nonatomic) IBOutlet UILabel *quadrupleLabel; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 创建4个点击手势识别器
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap)];
singleTap.numberOfTapsRequired = ;
singleTap.numberOfTouchesRequired = ;
// 附加到视图
[self.view addGestureRecognizer:singleTap]; UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTap)];
doubleTap.numberOfTapsRequired = ;
doubleTap.numberOfTouchesRequired = ;
[self.view addGestureRecognizer:doubleTap];
// 当doubleTap响应“失败”才运行singleTap
[singleTap requireGestureRecognizerToFail:doubleTap]; UITapGestureRecognizer *tripleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tripleTap)];
tripleTap.numberOfTapsRequired = ;
tripleTap.numberOfTouchesRequired = ;
[self.view addGestureRecognizer:tripleTap];
[doubleTap requireGestureRecognizerToFail:tripleTap]; UITapGestureRecognizer *quadrupleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(quadrupleTap)];
quadrupleTap.numberOfTapsRequired = ;
quadrupleTap.numberOfTouchesRequired = ;
[self.view addGestureRecognizer:quadrupleTap];
[tripleTap requireGestureRecognizerToFail:quadrupleTap];
} - (void)singleTap
{
self.singleLabel.text = @"Single Tap Detected";
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)( * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.singleLabel.text = @"";
});
} - (void)doubleTap
{
self.doubleLabel.text = @"Double Tap Detected";
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)( * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.doubleLabel.text = @"";
});
} - (void)tripleTap
{
self.tripleLabel.text = @"Triple Tap Detected";
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)( * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.tripleLabel.text = @"";
});
} - (void)quadrupleTap
{
self.quadrupleLabel.text = @"Quadruple Tap Detected";
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)( * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.quadrupleLabel.text = @"";
});
} @end

五、检测捏合和旋转

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController<UIGestureRecognizerDelegate>

@end

ViewController.h

//
// ViewController.m
// PinchMe
//
// Created by Jierism on 16/8/4.
// Copyright © 2016年 Jierism. All rights reserved.
// #import "ViewController.h" @interface ViewController () @property (strong,nonatomic) UIImageView *imageView; @end @implementation ViewController // 当前缩放比例,先前缩放比例
CGFloat scale,previousScale;
// 当前旋转角度,先前旋转角度
CGFloat rotation,previousRotation; - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
previousScale = ; UIImage *image = [UIImage imageNamed:@"yosemite-meadows"];
self.imageView = [[UIImageView alloc] initWithImage:image];
// 对图像启用交互功能
self.imageView.userInteractionEnabled = YES;
self.imageView.center = self.view.center;
[self.view addSubview:self.imageView]; // 建立捏合手势识别器
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(doPinch:)];
pinchGesture.delegate = self;
[self.imageView addGestureRecognizer:pinchGesture]; // 建立旋转手势识别器
UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(doRorate:)];
rotationGesture.delegate = self;
[self.imageView addGestureRecognizer:rotationGesture];
} - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
// 允许捏合手势和旋转手势同时工作。否则,先开始的手势识别器会屏蔽另一个
return YES;
} // 根据手势识别器中获得的缩放比例和旋转角度对图像进行变换
- (void)transformImageView
{
CGAffineTransform t = CGAffineTransformMakeScale(scale * previousScale, scale * previousScale);
t = CGAffineTransformRotate(t, rotation + previousRotation);
self.imageView.transform = t;
} - (void)doPinch:(UIPinchGestureRecognizer *)gesture
{
scale = gesture.scale;
[self transformImageView];
if (gesture.state == UIGestureRecognizerStateEnded) {
previousScale = scale * previousScale;
scale = ;
}
} - (void)doRorate:(UIRotationGestureRecognizer *)gesture
{
rotation = gesture.rotation;
[self transformImageView];
if (gesture.state == UIGestureRecognizerStateEnded) {
previousRotation = rotation + previousRotation;
rotation = ;
}
} @end

ViewController.m

六、自定义手势

//
// CheckMarkRecognizer.m
// CheckPlease
//
// Created by Jierism on 16/8/4.
// Copyright © 2016年 Jierism. All rights reserved.
// #import "CheckMarkRecognizer.h"
#import "CGPointUtils.h"
#import <UIKit/UIGestureRecognizerSubclass.h> // 一个重要目的是使手势识别器的state属性可写,子类将使用这个机制断言我们所观察的手势已成功完成 // 设置检测范围
static CGFloat const kMinimunCheckMarkAngle = ;
static CGFloat const kMaximumCheckMarkAngle = ;
static CGFloat const kMinimumCheckMarkLength = ; @implementation CheckMarkRecognizer{
// 前两个实例变量提供之前的线段
CGPoint lastPreviousPoint;
CGPoint lastCurrentPoint;
// 画出的线段长度
CGFloat lineLengthSoFar;
} // 用lastPreviousPoint和lastCurrentPoint组成第一条线段,跟第二条线段形成角度去完成手势
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self.view];
lastPreviousPoint = point;
lastCurrentPoint = point;
lineLengthSoFar = 0.0;
} - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint previousPoint = [touch previousLocationInView:self.view];
CGPoint currentPoint = [touch locationInView:self.view];
CGFloat angle = angleBetweenLines(lastPreviousPoint, lastCurrentPoint, previousPoint, currentPoint);
if (angle >= kMinimunCheckMarkAngle && angle <= kMaximumCheckMarkAngle && lineLengthSoFar > kMinimumCheckMarkLength) {
self.state = UIGestureRecognizerStateRecognized;
}
lineLengthSoFar += distanceBetweenPoints(previousPoint, currentPoint);
lastPreviousPoint = previousPoint;
lastCurrentPoint = currentPoint;
} @end

CheckMarkRecognizer.m

//
// ViewController.m
// CheckPlease
//
// Created by Jierism on 16/8/4.
// Copyright © 2016年 Jierism. All rights reserved.
// #import "ViewController.h"
#import "CheckMarkRecognizer.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UIImageView *imageView; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CheckMarkRecognizer *check = [[CheckMarkRecognizer alloc] initWithTarget:self action:@selector(doCheck:)];
[self.view addGestureRecognizer:check];
self.imageView.hidden = YES;
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} - (void)doCheck:(CheckMarkRecognizer *)check
{
self.imageView.hidden = NO;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)( * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.imageView.hidden = YES;
});
} @end

ViewController.m

iOS开发-轻点、触摸和手势的更多相关文章

  1. iOS开发系列之触摸事件

    基础知识 三类事件中触摸事件在iOS中是最常用的事件,这里我们首先介绍触摸事件. 在下面的例子中定义一个KCImage,它继承于UIView,在KCImage中指定一个图片作为背景.定义一个视图控制器 ...

  2. Android开发手记(30) 触摸及手势操作

    触摸操作在现在智能手机系统中起到举足轻重的作用,本文将对安卓中的触摸以及一些简单手势的操作进行简单的介绍. 1.触摸 首先是关于触摸的判断,有两种方法可以判断的触摸操作. (1)setOnTouchL ...

  3. ios开发-调用系统自带手势

    在 iPhone 或 iPad 的开发中,除了用 touchesBegan / touchesMoved / touchesEnded 这组方法来控制使用者的手指触控外,也可以用 UIGestureR ...

  4. iOS开发Quartz2D十二:手势解锁实例

    一:效果如图: 二:代码: #import "ClockView.h" @interface ClockView() /** 存放的都是当前选中的按钮 */ @property ( ...

  5. ios开发——实用技术OC-Swift篇&触摸与手势识别

    iOS开发学习之触摸事件和手势识别   iOS的输入事件 触摸事件 手势识别 手机摇晃 一.iOS的输入事件   触摸事件(滑动.点击) 运动事件(摇一摇.手机倾斜.行走),不需要人为参与的 远程控制 ...

  6. IOS 手势-轻点、触摸、手势、事件

    1.概念 手势是从你用一个或多个手指接触屏幕时开始,直到手指离开屏幕为止所发生的所有事件.无论手势持续多长时间,只要一个或多个手指仍在屏幕上,这个手势就存在. 触摸是指把手指放到IOS设备的屏幕上,从 ...

  7. iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控

    -- iOS事件全面解析 概览 iPhone的成功很大一部分得益于它多点触摸的强大功能,乔布斯让人们认识到手机其实是可以不用按键和手写笔直接操作的,这不愧为一项伟大的设计.今天我们就针对iOS的触摸事 ...

  8. iOS之触摸及手势

    触摸事件 iOS中的事件: 在用户使用app过程中,会产生各种各样的事件.iOS中的事件可以分为3大类型:    view的触摸事件处理: 响应者对象: 在iOS中不是任何对象都能处理事件,只有继承了 ...

  9. 转发:iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控

    -- iOS事件全面解析 转载来自崔江涛(KenshinCui) 链接:http://www.cnblogs.com/kenshincui/p/3950646.html 概览 iPhone的成功很大一 ...

随机推荐

  1. linux的HugePage与oracle amm关系

     如果Oracle 是11g以后的版本,那么默认创建的实例会使用Automatic Memory Management (AMM)的特性,该特性与HugePage不兼容. 在设置HugePage之前需 ...

  2. (转)c & c++内存分配

    一.预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于 数据结构中的栈. ...

  3. 开源的rtsp实现

    开源的rtsp实现                            ============== -- by BeagleTam                                  ...

  4. db file scattered read 等待事件

    db file scattered read 等待事件: 我们经常会见到db file scattered read  等待事件,在生产环境中,这个等待事件可能更为常见.这个事件表明用户进程正在读数据 ...

  5. UVA 12532-Interval Product(BIT)

    题意: 给n个数字的序列,C v p 把v位上的数字置成p , S l r代表求区间[l,r]各数字相乘得数的符号,对于每个S输出所得符号(’+‘,’-‘,’0‘) 分析: 开两个数组表示区间负数的个 ...

  6. [原创]cocos2d-x + Lua接入iOS原生SDK的实现方案

    相信很多朋友在使用cocos2d-x+lua开发游戏时都遇到过接入iOS原生SDK的问题,比如常见的接应用内支付SDK,广告SDK或是一些社交平台SDK等等,我也没少接过这类SDK.这篇文章主要是对我 ...

  7. 杂谈:HTML 5页面可视性API

    译文来源:http://www.ido321.com/1126.html 原文:HTML5 Page Visibility API 译文:HTML 5的页面可视性API 译者:dwqs 在早期,浏览器 ...

  8. PHP的MySQL扩展:MySQL数据库概述

    来源:http://www.ido321.com/1023.html 一.SQL:结构化查询语言 SQL(Structured Query Language)是高级的非过程化变成语言,专门用于查询和修 ...

  9. Azure终于支持大容量虚拟机了-最高32核,448G内存

    Azure终于支持大容量虚拟机了-最高32核,448G内存 最近微软Azure虚拟机旗下的大容量G系列虚拟机通用版本正式上线.G系列虚拟机方案提供公有云领域最大的内存容量.最强处理能力以及空间可观的本 ...

  10. kendoui-在线文本编辑器

    文本编辑器用过很多,fckeditor是我之前用的最多的,但是问题也有很多,诸如安全问题,浏览器兼容问题..所以最近也一直在找替代产品,正好在研究kendo,所以就尝试了下kendo提供的edit控件 ...