iOS Programming – 触摸事件处理(2)

时间:2022-04-22
本文章向大家介绍iOS Programming – 触摸事件处理(2),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

iOS Programming – 触摸事件处理(2)

在上一篇《iOS Programming – 触摸事件处理(1)》中了解触摸、事件和响应者之后,接下去学习如何处理用户的触摸事件。首先触摸的对象是视图,而视图的类UIView继承了UIRespnder类,但是要对事件作出处理,还需要重写UIResponder类中定义的事件处理函数。根据不通的触摸状态,程序会调用相应的处理函数,这些函数包括以下几个:

            -(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方法。而这几个方法被调用时,正好对应了UITouch类中phase属性的4个枚举值。

上面的四个事件方法,在开发过程中并不要求全部实现,可以根据需要重写特定的方法。对于这4个方法,都有两个相同的参数:NSSet类型的touches和UIEvent类型的event。其中touches表示触摸产生的所有UITouch对象,而event表示特定的事件。因为UIEvent包含了整个触摸过程中所有的触摸对象,因此可以调用allTouches方法获取该事件内所有的触摸对象,也可以调用touchesForVIew:或者touchesForWindows:取出特定视图或者窗口上的触摸对象。在这几个事件中,都可以拿到触摸对象,然后根据其位置,状态,时间属性做逻辑处理。

例如:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch =  [touches anyObject];
 if(touch.tapCount == 2)
    {
        self.view.backgroundColor = [UIColor redColor];
    }
}

上面的例子说明在触摸手指离开后,根据tapCount点击的次数来设置当前视图的背景色。不管时一个手指还是多个手指,轻击操作都会使每个触摸对象的tapCount加1,由于上面的例子不需要知道具体触摸对象的位置或时间等,因此可以直接调用touches的anyObject方法来获取任意一个触摸对象然后判断其tapCount的值即可。

检测tapCount可以放在touchesBegan也可以touchesEnded,不过一般后者跟准确,因为touchesEnded可以保证所有的手指都已经离开屏幕,这样就不会把轻击动作和按下拖动等动作混淆。

轻击操作很容易引起歧义,比如当用户点了一次之后,并不知道用户是想单击还是只是双击的一部分,或者点了两次之后并不知道用户是想双击还是继续点击。为了解决这个问题,一般可以使用“延迟调用”函数。

例如:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch =  [touches anyObject];
 if(touch.tapCount == 1)
    {
        [self performSelector:@selector(setBackground:) withObject:[UIColor blueColor] afterDelay:2];
        self.view.backgroundColor = [UIColor redColor];
    }
}

上面代码表示在第一次轻击之后,没有直接更改视图的背景属性,而是通过performSelector:withObject:afterDelay:方法设置2秒中后更改。

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch =  [touches anyObject];
 if(touch.tapCount == 2)
    {
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(setBackground:) object:[UIColor redColor]];
        self.view.backgroundColor = [UIColor redColor];
    }
}

双击就是两次单击的组合,因此在第一次点击的时候,设置背景色的方法已经启动,在检测到双击的时候先要把先前对应的方法取消掉,可以通过调用NSObject类的cancelPreviousPerformRequestWithTarget:selector:object方法取消指定对象的方法调用,然后调用双击对应的方法设置背景色为红色。

下面举个例子创建可以拖动的视图,这个主要通过触摸对象的位置坐标来实现。因此调用触摸对象的locationInView:方法即可。

例如:

CGPoint originalLocation;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    originalLocation = [touch locationInView:self.view];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint currentLocation = [touch locationInView:self.view];
    CGRect frame = self.view.frame;
    frame.origin.x += currentLocation.x-originalLocation.x;
    frame.origin.y += currentLocation.y-originalLocation.y;   
    self.view.frame = frame;
}

这里先在touchesBegan中通过[touch locationInView:self.view]获取手指触摸在当前视图上的位置,用CGPoint变量记录,然后在手指移动事件touchesMoved方法中获取触摸对象当前位置,并通过于与原始位置的差值计算出移动偏移量,再设置当前视图的位置。