为什么 UINavigationBar 会窃取触摸事件? [英] Why does UINavigationBar steal touch events?

查看:16
本文介绍了为什么 UINavigationBar 会窃取触摸事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义 UIButton,其中 UILabel 添加为子视图.仅当我在上界下方约 15 点触摸按钮时,按钮才会执行给定的选择器.当我点击该区域上方时,什么也没有发生.

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

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

图片在这里p>

带有 4 个按钮的视图位于 NavigationBar 下方.并且当触摸顶部的篮球"时,BackButton 得到触摸事件,当触摸顶部的钢琴"时,rightBarButton(如果存在)得到触摸.如果不存在,则什么都没有发生.

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

我还发现 this 主题与我的问题有关,但也没有答案.

解决方案

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

Keith 在 Apple Developer Technical Support 上,2010 年 5 月 18 日(iPhone OS 3):

<块引用>

我建议您避免在靠近导航栏或工具栏的位置使用触敏 UI.这些区域通常被称为倾斜因素",使用户更容易在按钮上执行触摸事件,而不会遇到执行精确触摸的困难.例如,UIButton 也是如此.

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

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

CustomWindow.h

@interface CustomWindow: UIWindow@结尾

自定义窗口.m

@implementation 自定义窗口- (void) sendEvent:(UIEvent *)event{布尔标志 = 是;开关([事件类型]){案例 UIEventTypeTouches://[self catchUIEventTypeTouches: 事件];如果您需要对事件执行某些操作,请执行for (UITouch *touch in [event allTouches]) {if ([触摸阶段] == UITouchPhaseBegan) {for (int i=0; i<[self.subviews count]; i++) {//获取屏幕上的手指位置CGPoint location = [touch locationInView:[self.subviews objectAtIndex:i]];//报告触摸NSLog(@"[%@] touchesBegan (%i,%i)", [[self.subviews objectAtIndex:i] class],(NSInteger) location.x, (NSInteger) location.y);if (((NSInteger)location.y) == 64) {标志=否;}}}}休息;默认:休息;}如果(!标志)返回;//什么都不做/*重要*/[super sendEvent:(UIEvent *)event];/*重要*/}@结尾

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

现在当我触摸导航栏下的区域时,什么也没有发生.

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

I have a custom UIButton with UILabel added as subview. Button perform given selector only when I touch it about 15points lower of top bound. And when I tap above that area nothing happens.

I found out that it hasn't caused by wrong creation of button and label, because after I shift the button lower at about 15 px it works correctly.

UPDATE I forgot to say that button located under the UINavigationBar and 1/3 of upper part of the button don't get touch events.

Image was here

View with 4 buttons is located under the NavigationBar. And when touch the "Basketball" in top, BackButton get touch event, and when touch "Piano" in top, then rightBarButton (if exists) get touch. If not exists, nothing happened.

I didn't find this documented feature in App docs.

Also I found this topic related to my problem, but there is no answer too.

解决方案

I found out the answer here(Apple Developer Forum).

Keith at Apple Developer Technical Support, on 18th May 2010 (iPhone OS 3):

I recommend that you avoid having touch-sensitive UI in such close proximity to the nav bar or toolbar. These areas are typically known as "slop factors" making it easier for users to perform touch events on buttons without the difficulty of performing precision touches. This is also the case for UIButtons for example.

But if you want to capture the touch event before the navigation bar or toolbar receives it, you can subclass UIWindow and override: -(void)sendEvent:(UIEvent *)event;

Also I found out,that when I touch the area under the UINavigationBar, the location.y defined as 64,though it was not. So I made this:

CustomWindow.h

@interface CustomWindow: UIWindow 
@end

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

In AppDelegate class I use CustomWindow instead of UIWindow.

Now when I touch area under navigation bar, nothing happens.

My buttons still don't get touch events,because I don't know how to send this event (and change coordinates) to my view with buttons.

这篇关于为什么 UINavigationBar 会窃取触摸事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆