一、触摸事件的处理方式
1.在IOS上,事件有多种形式:触摸事件,运动事件,远程控制事件。
2.触摸事件的处理方法
响应者类通过复写以下方法,可以监听触摸事件
(1)当一个或者多个手指触摸屏幕时:
- (void)touchesBegan:(NSSet *)touches withEvent:
(2)当一个或多个手指在屏幕上移动时:
- (void)touchesMoved:(NSSet *)touches withEvent:
(3)当一个或者多个手指离开屏幕时:
- (void)touchesEnded:(NSSet )touches withEvent:(UIEvent )event;
(4)当触摸序列被系统事件(诸如电话呼入)所取消时:
- (void)touchesCancelled:(NSSet *)touches withEvent:
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//1.是否响应交互事件,默认为yes,UIImageView默认no
//self.userInteractionEnabled = NO;
//2.多点触摸,默认是no
self.multipleTouchEnabled= YES;
}
return self;
}
----------
//1.触摸开始(当用户触摸屏幕时调用视图如下方法)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//UITouch --- 手指头的个数,一个touch表示一根手指(触摸点)
//NSSet集合,保存UITouch对象,有几个触摸点,set里面就有几个触摸对象
//点击的次数
UITouch *touch = [touches anyObject];
NSLog(@"tap count :%ld",touch.tapCount);
//触摸的阶段,触摸事件在屏幕上有一个周期,即触摸开始、移动、结束和中途取消。而通过phase可以查看当前触摸事件在一个周期中所处的状态。
NSLog(@"phase :%ld",touch.phase);
//在视图上的位置坐标,这里返回的位置是针对VIEW的坐标系
CGPoint point = [touch locationInView:self];
NSLog(@"location in View:%@",NSStringFromCGPoint(point));
//在window上的位置
CGPoint windowPoint = [touch locationInView:[UIApplication sharedApplication].keyWindow];
NSLog(@"location in window :%@",NSStringFromCGPoint(windowPoint));
//在视图上前一个点的坐标
CGPoint prepoint = [touch previousLocationInView:self];
NSLog(@"previouslocation in preview :%@",NSStringFromCGPoint(prepoint));
}
----------
//2.触摸移动
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
//在视图上的位置坐标
CGPoint point = [touch locationInView:self];
NSLog(@"location in View:%@",NSStringFromCGPoint(point));
//在视图上前一个点的坐标
CGPoint prepoint = [touch previousLocationInView:self];
NSLog(@"previouslocation in preview :%@",NSStringFromCGPoint(prepoint));
//触摸的阶段
NSLog(@"phase :%ld",touch.phase);
}
----------
//3.触摸结束
//- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
//{
// UITouch *touch = [touches anyObject];
// //触摸的阶段
// NSLog(@"phase :%ld",touch.phase);
//}
//触摸取消,一般用不到
//- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
@end
eg:下面介绍一个处理轻击事件的Demo:
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(20, 20, 100, 100);
[button setTitle:@"ClickAction" forState:UIControlStateNormal];
[button addTarget:self
action:@selector(buttonAction:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
----------
- (void)buttonAction:(UIButton *)btn
{
NSLog(@"action");
}
----------
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if (touch.tapCount == 1)//单机
{
[self performSelector:@selector(singleTap)
withObject:nil
afterDelay:.2];
}else if (touch.tapCount == 2)//双击
{
//*先取消单机,这一点很重要*
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:@selector(singleTap)
object:nil];
[self doubleTap];
}
}
----------
- (void)singleTap
{
NSLog(@"单击");
}
- (void)doubleTap
{
NSLog(@"双击");
}
2.运动事件
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event;
3.远程控制:(比如耳机线按钮控制音乐播放) - (void)remoteControlReceivedWithEvent:(UIEvent *)event;
二、事件传递的过程
三、响应者链
响应者对象是一个能接受并处理事件的对象。UIResponser是所有响应者对象的基类。
响应者链表示一系列的响应者对象。事件被交由第一响应者对象处理,如果第一响应者不处理,事件被沿着响应者链向上传递,交给下一响应者(next responder)。
下面是一个next responder的view的类目
#import "UIView+ViewController.h"
@implementation UIView (ViewController)
- (UIViewController *)viewController
{
id next = [self nextResponder];
while (next != nil) {
if ([next isKindOfClass:[UIViewController class]]) {
UIViewController *viewCtrl = next;
return viewCtrl;
}
next = [next nextResponder];
}
return nil;
}
@end
四、手势识别器
UIGestureRecognizer类是用于检测和识别用户使用设备时所用的手势。它是一个抽象类,定义了所有手势的基本行为。以下是UIGestureRecognizer子类,用于处理具体的用户手势行为:
UITapGestureRecognizer(轻击)
UIPinchGestureRecognizer(捏合)
UIPanGestureRecognizer(平移)
UISwipeGestureRecognizer(清扫)
UILongPressGestureRecognizer(长按)
UIRotationGestureRecognizer(旋转)
其中注意的是区别两种手势(一只手单击、双击)
eg:
//一只手单击
UITapGestureRecognizer *tap1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapOnce)];
tap1.numberOfTapsRequired = 1;
tap1.numberOfTouchesRequired = 1;
[self.view addGestureRecognizer:tap1];
//一只手双击
UITapGestureRecognizer *tap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapTwice)];
tap2.numberOfTapsRequired = 2;
tap2.numberOfTouchesRequired = 1;
[self.view addGestureRecognizer:tap2];
[tap1 requireGestureRecognizerToFail:tap2];
----------
//两只手单击
UITapGestureRecognizer *tap3 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapOnce)];
tap3.numberOfTouchesRequired = 2;
[self.view addGestureRecognizer:tap3];
//两只手双击
UITapGestureRecognizer *tap4 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapTwice)];
tap4.numberOfTapsRequired = 2;
tap4.numberOfTouchesRequired = 2;
[self.view addGestureRecognizer:tap4];
//区别两种手势
[tap3 requireGestureRecognizerToFail:tap4];
----------
//一只手向右轻扫
UISwipeGestureRecognizer *swip2 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swip2Action)];
swip2.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:swip2];
----------
//捏合手势
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchAction:)];
[self.view addGestureRecognizer:pinch];
----------
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressAction:)];
[self.view addGestureRecognizer:longPress];
----------
//长按手势
- (void)longPressAction:(UILongPressGestureRecognizer *)sender
{
NSLog(@"长按");
if (sender.state == UIGestureRecognizerStateBegan)
{
NSLog(@"开始");
}else if (sender.state == UIGestureRecognizerStateChanged)
{
NSLog(@"移动");
}else if (sender.state == UIGestureRecognizerStateEnded)
{
NSLog(@"结束");
}
}