下面介绍另外两个UIGestureRecognizer子类:UILongPressGestureRecognizer和UIPanGestureRecognizer。当用户按住某根线条(长按)不放时,TouchTracker应该选中该线条。如果某根线条通过上述手势选中,就应该允许用户拖移(pan)这根线条至新位置。
本节先介绍UILongPressGestureRecognizer。在BNRDrawView.m的initWithFrame:中先创建一个UILongPressGestureRecognizer对象,然后将该对象附着在BNRDrawView对象上,代码如下:
[self addGestureRecognizer:tapRecognizer];
UILongPressGestureRecognizer *pressRecognizer
= [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(longPress:)];
[self addGestureRecognizer:pressRecognizer];
当用户按住BNRDrawView对象不放时,附着在该对象上的UILongPressGesture- Recognizer对象就会向其发送longPress:消息。UILongPressGestureRecognizer对象默认会将持续时间超过0.5秒的触摸事件识别为长按手势。设置UILongPressGesture- Recognizer对象的minimumPressDuration属性可以修改这个时间。
“点击屏幕”是一种简单的手势,只有一个事件。UITapGestureRecognizer对象一旦识别出按下手势,就会触发按下事件并结束该手势的识别过程。“长按屏幕”则不同,UILongPressGestureRecognizer对象在识别出长按手势后,会持续跟踪该手势并在不同的阶段分别触发三种不同的事件。
例如,当用户触摸某个UIView对象后,UILongPressGestureRecognizer对象会将这个触摸事件识别为“可能会发生”的长按手势。为了能够准确地识别长按手势,UILongPressGestureRecognizer对象必须等待后续事件,根据触摸时间做下一步的判断。
当触摸的时间足够长时,UILongPressGestureRecognizer对象就会将其识别为长按手势并触发“长按开始”事件。当用户的手指离开屏幕时,该对象会触发“长按结束”事件。
当某个UIGestureRecognizer子类对象触发特定的事件后,其state属性会发生变化。以UILongPressGestureRecognizer对象为例,和上述三种事件相对应的state属性分别为:UIGestureRecognizerStatePossible、UIGestureRecognizerStateBegan和UIGestureRecognizerStateEnded。
当某个UIGestureRecognizer子类对象的state属性发生变化时(除了切换至UIGestureRecognizerStatePossible的情况),该对象就会向其目标对象发送指定的动作消息。所以当某个长按手势开始和结束时,相应的UILongPressGestureRecognizer对象都会向其目标对象发送同一个消息。和该消息匹配的方法可以通过UIGestureRecognizer对象的state属性来判断当前的事件类型,然后根据不同的事件类型执行不同的代码。
longPress:的实现逻辑为:当BNRDrawView对象收到longPress:时,如果事件类型是“开始”,就应该根据手势发生时的位置选中距离最近的那根线条。这样用户就可以通过长按屏幕选中某根线条。如果事件类型是“结束”,就应该取消当前选中的线条。
在BNRDrawView.m中实现longPress:,代码如下:
- (void)longPress:(UIGestureRecognizer *)gr
{
if (gr.state == UIGestureRecognizerStateBegan) {
CGPoint point = [gr locationInView:self];
self.selectedLine = [self lineAtPoint:point];
if (self.selectedLine) {
[self.linesInProgress removeAllObjects];
}
} else if (gr.state == UIGestureRecognizerStateEnded) {
self.selectedLine = nil;
}
[self setNeedsDisplay];
}
构建并运行应用。画一根线条,按住线条不放。TouchTracker应该会用绿色重画这根线条。