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

时间:2022-12-15 13:03:11

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类型的touchesUIEvent类型的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点击的次数来设置当前视图的背景色。不管时一个手指还是多个手指,轻击操作都会使每个触摸对象的tapCount1,由于上面的例子不需要知道具体触摸对象的位置或时间等,因此可以直接调用touchesanyObject方法来获取任意一个触摸对象然后判断其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];
    }
}

            上面代码表示在第一次轻击之后,没有直接更改视图的背景属性,而是通过performSelectorwithObjectafterDelay方法设置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方法中获取触摸对象当前位置,并通过于与原始位置的差值计算出移动偏移量,再设置当前视图的位置。