为什么UINavigationBar会窃取触摸事件?

Ale*_*der 19 iphone objective-c uibutton uilabel ios4

我有一个自定义的UIButton,UILabel被添加为子视图.按钮仅在我触摸顶部边界约15个点时执行给定选择器.当我在该区域上方点击时,没有任何反应.

我发现它不是由于按钮和标签的错误创建造成的,因为在我将按钮向下移动约15 px后,它正常工作.

更新我忘了说位于UINavigationBar下面的按钮和按钮上半部分的1/3没有触摸事件.

图像在这里

带有4个按钮的视图位于NavigationBar下方.当触摸顶部的"篮球"时,BackButton会触摸事件,当触摸顶部的"Piano"时,则右边的BarButton(如果存在)触摸.如果不存在,则什么也没发生.

我没有在App文档中找到这个记录的功能.

我也发现这个话题与我的问题有关,但也没有答案.

And*_*scu 29

我注意到如果你将userInteractionEnabled设置为OFF,则NavigationBar不再"窃取"触摸.

所以你必须继承你的UINavigationBar并在你的CustomNavigationBar中执行以下操作:

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

    if ([self pointInside:point withEvent:event]) {
        self.userInteractionEnabled = YES;
    } else {
        self.userInteractionEnabled = NO;
    }

    return [super hitTest:point withEvent:event];
}
Run Code Online (Sandbox Code Playgroud)

有关如何子类UINavigationBar的信息,您可以在这里找到.

  • 这个解决方案给我带来了一个错误,有时只导航回导航栏,但视图没有删除或变黑. (3认同)

Ale*_*der 16

我在这里找到了答案(Apple开发者论坛).

2010年5月18日,Apple开发者技术支持部门的Keith(iPhone OS 3):

我建议您避免在导航栏或工具栏附近使用触敏UI.这些区域通常被称为"slop因子",使得用户更容易在按钮上执行触摸事件而不会难以执行精确触摸.例如,对于UIButton也是如此.

但是如果你想在导航栏或工具栏接收之前捕获触摸事件,你可以继承子UIWindow并覆盖: - (void)sendEvent:(UIEvent*)event;

我还发现,当我触摸UINavigationBar下的区域时,location.y定义为64,尽管它不是.所以我做了这个:

CustomWindow.h

@interface CustomWindow: UIWindow 
@end
Run Code Online (Sandbox Code Playgroud)

CustomWindow.m

@implementation CustomWindow
- (void) sendEvent:(UIEvent *)event
{       
  BOOL flag = YES;
  switch ([event type])
  {
   case UIEventTypeTouches:
        //[self catchUIEventTypeTouches: event]; perform if you need to do something with event         
        for (UITouch *touch in [event allTouches]) {
          if ([touch phase] == UITouchPhaseBegan) {
            for (int i=0; i<[self.subviews count]; i++) {
                //GET THE FINGER LOCATION ON THE SCREEN
                CGPoint location = [touch locationInView:[self.subviews objectAtIndex:i]];

                //REPORT THE TOUCH
                NSLog(@"[%@] touchesBegan (%i,%i)",  [[self.subviews objectAtIndex:i] class],(NSInteger) location.x, (NSInteger) location.y);
                if (((NSInteger)location.y) == 64) {
                    flag = NO;
                }
             }
           }  
        }

        break;      

   default:
        break;
  }
  if(!flag) return; //to do nothing

    /*IMPORTANT*/[super sendEvent:(UIEvent *)event];/*IMPORTANT*/
}

@end
Run Code Online (Sandbox Code Playgroud)

在AppDelegate类中,我使用CustomWindow而不是UIWindow.

现在,当我触摸导航栏下的区域时,没有任何反应.

我的按钮仍然没有触摸事件,因为我不知道如何使用按钮将此事件(和更改坐标)发送到我的视图.