当前位置:编程学习 > wap >>

iphone中的UITouch

手指在屏幕上能达到的精度和鼠标指针有很大的不同。当用户触击屏幕时,接触

区域实际上是椭圆形的,而且比用户想像的位置更靠下一点。根据触摸屏幕的手指、手指的尺寸、手指接触屏幕的力量、手指的方向、以及其它因素的不同,其“接触部位”的尺寸和形状也有所不同。底层的多点触摸系统会分析所有的这些信息,为您计算出单一的触点。

 

UIResponder 是所有响应者对象的基类,

它不仅为事件处理,而且也为常见的响应者行为定义编程接口。UIApplication、UIView、和所有从UIView 派生出来的UIKit 类(包括UIWindow)都直接或间接地继承自UIResponder类。

 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

UITouch* touch = [touches anyObject];

NSUInteger numTaps = [touch tapCount];

if (numTaps < 2) {

[self.nextResponder touchesBegan:touches withEvent:event];

} else {

[self handleDoubleTap:touch];

}

}

 

缺省情况下,视图会接收触摸事件。但是,您可以将其userInteractionEnabled

属性声明设置为NO,关闭事件传递的功能。

 

在一定的时间内关闭事件的传递。应用程序可以调用UIApplication 的

beginIgnoringInteractionEvents 方法,并在随后调用endIgnoringInteractionEvents 方法来实现这个目的。

 

缺省情况下,视图只接收多点触摸序列的第一个触摸事件,而忽略

所有其它事件。如果您希望视图处理多点触摸,就必须使它启用这个功能。在代码或Inte易做图ce Builder 的查看器窗口中将视图的multipleTouchEnabled 属性设置为YES,就可以实现这个目标。

将事件传递限制在某个单独的视图上。缺省情况下,视图的exclusiveTouch 属性被设置为NO。将这个属性设置为YES 会使相应的视图具有这样的特性:即当该视图正在跟踪触摸动作时,窗口中的其它视图无法同时进行跟踪,它们不能接收到那些触摸事件。

多点触摸:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

 

当一个或多个手指触碰屏幕时,发送touchesBegan:withEvent:消息。

当一个或多个手指在屏幕上移动时,发送touchesMoved:withEvent:消息。

当一个或多个手指离开屏幕时,发送touchesEnded:withEvent:消息。

当触摸序列被诸如电话呼入这样的系统事件所取消时,发送touchesCancelled:withEvent:消息。

上面这些方法都和特定的触摸阶段(比如UITouchPhaseBegan)相关联,该信息存在于UITouch 对象的phase 属性声明中。

为了处理给定阶段的事件,响应者对象常常从传入的集合参数中取得一或多个UITouch 对象,然后考察这些对象的属性或取得它们的位置(如果需要处理所有触摸对象,可以向该NSSet 对象发送anyObject 消息)。UITouch 类中有一个名为locationInView:的重要方法,如果传入self 参数值,它会给出触摸动作在响应者坐标系统中的位置(假定该响应者是一个UIView 对象,且传入的视图参数不为nil)。另外,还有一个与之平行的方法,可以给出触摸动作之前位置(previousLocationInView:)。UITouch 实例的属性还可以给出发生多少次触

碰(tapCount)、触摸对象的创建或最后一次变化发生在什么时间(timestamp)、以及触摸处于什么阶段(phase)。

 

- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event

{

UITouch *touch = [touches anyObject];

if ([touch tapCount] == 2) {

CGPoint tapPoint = [theTouch locationInView:self];

// Process a double-tap gesture

}

}

在touchesEnded:withEvent:方法中,当触击次数为一时,响应者对象就向自身发送一个performSelector:withObject:afterDelay:消息,其中的选择器标识由响应者对象实现的、用于处理单击手势的方法;第二个参数是一个NSValue 或NSDictionary 对象,用于保存相关的UITouch 对象;时延参数则表示单击和双击手势之间的合理时间间隔。

在touchesBegan:withEvent:方法中,如果触击次数为二,响应者对象会向自身发送一个cancelPreviousPerformRequestsWithTarget:消息,取消当前被挂起和延期执行的调用。如果触碰次数不为二,则在指定的延时之后,先前步骤中由选择器标识的方法就会被调用,以处理单击手势。

 

在视图中跟踪碰擦手势

#define HORIZ_SWIPE_DRAG_MIN 12

#define VERT_SWIPE_DRAG_MAX 4

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

UITouch *touch = [touches anyObject];

startTouchPosition = [touch locationInView:self];

}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

{

UITouch *touch = [touches anyObject];

CGPoint currentTouchPosition = [touch locationInView:self];

// If the swipe tracks correctly.

if (fabsf(startTouchPosition.x - currentTouchPosition.x) >= HORIZ_SWIPE_DRAG_MIN

&&

fabsf(startTouchPosition.y - currentTouchPosition.y) <=

VERT_SWIPE_DRAG_MAX)

{

// It appears to be a swipe.

if (startTouchPosition.x < currentTouchPosition.x)

[self myProcessRightSwipe:touches withEvent:event];

else

[self myProcessLeftSwipe:touches withEvent:event];

}

else

{

// Process a non-swipe event.

}

}

 

处理复杂的多点触摸序列

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

UITouch *touch = [[event allTouches] anyObject];

// Only move the placard view if the touch was in the placard view

if ([touch view] != placardView) {

// On double tap outside placard view, update placard's display string

if ([touch tapCount] == 2) {

[placardView setupNextDisplayString];

}

return;

}

// "Pulse" the placard view by scaling up then down

// Use UIView's built-in animation

[UIView beginAnimations:nil context:NULL];

[UIView setAnimationDuration:0.5];

CGAffineTransform transform = CGAffineTransformMakeScale(1.2, 1.2);

placardView.transform = transform;

[UIView commitAnimations];

[UIView beginAnimations:nil context:NULL];

[UIView setAnimationDuration:0.5];

transform = CGAffineTransformMakeScale(1.1, 1.1);

placardView.transform = transform;

[UIView commitAnimations];

// Move the placardView to under the touch

[UIView beginAnimations:nil context:NULL];

[UIView setAnimationDuration:0.25];

placardView.center = [self convertPoint:[touch locationInView:self]

fromView:placardView];

[UIView commitAnimations];

}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

{

UITouch *touch = [[event allTouches] anyObject];

// If the touch was in the placardView, move the placardView to its location

if ([touch view] == placardView) {

CGPoint location = [touch locationInView:self];

location = [self convertPoint:location fromView:placardView];

placardView.center = location;

return;

}

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

{

UITouch *touch = [[event allTouches] anyObject];

// If the touch was in the placardView, bounce it back to the center

if ([touch view] == placardView) {

// Disable user interaction so subsequent touches don't interfere with animation

self.userInteractionEnabled = NO;

[self animatePlacardViewToCenter];

return;

}

}

 

在事件处理代码中,您可以将触摸状态的相关位置保存下来,以便在必要时和变化之后的UITouch 实例进行比较。定制视图可以用UIView 的hitTest:withEvent:方法或CALayer 的hitTest:方法来寻找接收触摸事件的子视图或层,进而正确地处理事件。下面的例子用于检测定制视图的层中的“Info” 图像是否被触碰。

- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {

CGPoint location = [[touches anyObject] location

补充:移动开发 , IOS ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,