2011-06-17 136 views
1

我试图检测用户在视图中触摸时的位置。该视图包含一些按钮和其他UIKit控件。我想检测这些触摸事件,但不会消耗它们。检测触摸并触摸包含UIControls的视图

我已经试过两种方法,但也已经足够了:

首先,我增加了一个透明的覆盖重写-touchesBegan:withEvent:方法和-touchesEnded:withEvent:方法和事件与

转发到下一个响应者
[self.nextResponder touchesBegan:touches withEvent:event] 

但是,似乎UIKit对象忽略所有转发的事件。

接下来,我尝试覆盖-pointInside:withEvent:和-hitTest:withEvent:。这很好地检测触摸下来事件,但是pointInside ::和hitTest ::不会在触摸时调用up(即[[[allEvent] anyObject]阶段]永远不会等于UITouchPhaseEnded。

在不干扰与底层UIControls交互的情况下,检测触摸和触摸事件的最佳方式是什么?

+0

我没有看到为什么响应者会忽略'touchesBegan:withEvent:',因为它已经被发送到其他具有相同事件的其他人。这违背了响应者链条的重点。你确定'nextResponder'正在返回一些东西吗? –

+0

@Peter“UIKit框架的类没有设计用来接收未绑定到它们的触摸;从程序上讲,这意味着UITouch对象的view属性必须持有对框架对象的引用才能触摸如果你想有条件地向你的应用程序中的其他应答者转发接触,所有这些应答者应该是你自己的UIView子类的实例。“ (http://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MultitouchEvents/MultitouchEvents.html) – tba

回答

-1

根据Event Handling Guide for iOS 你有3种选择:使用重叠视图

3)设计,使您不必

2):

1)子类的UIWindow覆盖的SendEvent要做到这一点......所以更像2个选项。

下面是使用UIWindow子类简化苹果示例;

1)将NIB中窗口的类更改为UIWindow的子类。 2)把这个方法放在.m文件中。

- (void)sendEvent:(UIEvent *)event 
{ 
    NSSet * allTouches = [event allTouches]; 

    NSMutableSet *began = nil; 
    NSMutableSet *moved = nil; 
    NSMutableSet *ended = nil; 
    NSMutableSet *cancelled = nil; 

    // sort the touches by phase so we can handle them similarly to normal event dispatch 
    for(UITouch *touch in allTouches) { 
     switch ([touch phase]) { 
      case UITouchPhaseBegan: 
       if (!began) began = [NSMutableSet set]; 
       [began addObject:touch]; 
       break; 
      case UITouchPhaseMoved: 
       if (!moved) moved = [NSMutableSet set]; 
       [moved addObject:touch]; 
       break; 
      case UITouchPhaseEnded: 
       if (!ended) ended = [NSMutableSet set]; 
       [ended addObject:touch]; 
       break; 
      case UITouchPhaseCancelled: 
       if (!cancelled) cancelled = [NSMutableSet set]; 
       [cancelled addObject:touch]; 
       break; 
      default: 
       break; 
     } 

     // call our methods to handle the touches 
     if (began) 
     { 
      NSLog(@"the following touches began: %@", began); 
     }; 
     if (moved) 
     { 
      NSLog(@"the following touches were moved: %@", moved); 
     }; 
     if (ended) 
     { 
      NSLog(@"the following touches were ended: %@", ended); 
     }; 
     if (cancelled) 
     { 
      NSLog(@"the following touches were cancelled: %@", cancelled); 
     }; 
    } 
    [super sendEvent:event]; 
} 

它有太多的输出,但你会明白......并且可以使你的逻辑适合你想要的地方。

+0

如果我在叠加层中检测到触摸,调用[super touchesBegan:]不会转发该事件到下面的意见。如果我在父视图中检测到触摸,则一个UIButton子消耗触动,而我的touchesBegan:永远不会被调用。 – tba

+0

让我跑一个快速测试... –

+0

你说的对,UIView吞咽事件,我修改了UIWindow子类的苹果示例。 –