触摸事件
UIView
是 UIResponder
的子类,因此重写下述几个方法可以处理不同的触摸事件:
- 一根或多根手指触摸屏幕:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- 一根或多根手指在屏幕上移动:
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- 一根或多根手指离开屏幕:
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- 在触摸操作正常结束前,某个系统事件打断了触摸过程:
- (void)touchesCancelled:(nullable NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
单点触摸
当系统检测到手指触摸屏幕的事件后,就会创建 UITouch
对象(一根手指的触摸事件对应一个 UITouch
对象)。发生触摸事件的 UIView
对象会收到 touchesBegan:withEvent:
消息,系统传入的第一个实参 touches
(NSSet
对象) 会包含所有相关的 UITouch
对象。
示例代码:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 根据触摸位置创建 BNRLine 对象
CGPoint location = [[touches anyObject] locationInView:self];
self.currentLine = [[BNRLine alloc] init];
self.currentLine.begin = location;
self.currentLine.end = location;
[self setNeedsDisplay];
}
当手指在屏幕上移动时,系统会更新相应的 UITouch
对象,为其重新设置对应的手指在屏幕上的位置。最初发生触摸事件的那个 UIView
对象会收到 touchesMoved:withEvent:
消息,系统传入的第一个参数 touches
(NSSet
对象) 会包含所有相关的 UITouch
对象,而这些 UITouch
对象都是最初发生触摸事件创建的。
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
CGPoint location = [[touches anyObject] locationInView:self];
self.currentLine.end = location;
[self setNeedsDisplay];
}
当手指离开屏幕时,系统会最后一次更新相应的 UITouch
对象,为其重新设置对应的手指在屏幕上的位置。接着,最初发生该触摸时间的视图会收到 touchesEnded:withEvent:
消息。当收到消息的视图执行完 touchesEnded:withEvent:
后,系统就会释放和当前事件有关的 UITouch
对象。
示例代码:
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self.finishedLines addObject:self.currentLine];
self.currentLine = nil;
[self setNeedsDisplay];
}
多点触摸
默认情况下,视图在同一时刻只能接受一个触摸事件。若要同时接受多个触摸事件,则需进行设置:
self.multipleTouchEnabled = YES;
为更好地解决 B�N�RLine
属性与触摸事件之间的对应关系,用 NSMutableDictionary
对象保存正在绘制的多个线条,并使用 valueWithNonretainedObject:
方法将 UITouch
对象的内存地址封装为 NSValue
对象的键,对象图如下所示:
示例代码:
//将 UITouch 对象的内存地址封装为 NSValue 对象,作为 BNRLine 对象的键
NSValue *key = [NSValue valueWithNonretainedObject:t];
此外,还可以下述代码来查看触摸事件的发生顺序:
// 向控制台输出日志,查看触摸事件发生顺序
NSLog(@"%@", NSStringFromSelector(_cmd));
代码地址:
https://github.com/Ranch2014/iOSProgramming4ed/tree/master/12-TouchEventsAndUIResponder/TouchTracker
《iOS编程(第4版)》 笔记