触摸未调用导航栏~8像素内的事件

时间:2011-10-18 11:33:35

标签: iphone uiview uinavigationbar

我有一个应用程序,其中有三个按钮(实际为UIView)在导航栏下方水平

三个按钮的尺寸足够大(例如,比后退按钮大),但是当击中大致位于前三分之一时,它们不会响应触摸。

我知道导航栏正下方的这个区域对于后退按钮和其他UINavigation项目来说是“保留”的,其触摸区域扩展到导航栏之外(相当大的余量),但在某些区域中例如,附近甚至没有导航项目来窃取事件,我的观点仍然没有回复。

奇怪的是,我在我的UIView中调用hitTest方法,而不是touchesBegan / Ended / etc。

结果是按下按钮非常困难,如果按钮位于UINavigationItem附近,该项目将窃取该事件,即使在hitTest我正在返回正确的{{} 1}}到系统。

不幸的是,我是实施者,而不是设计师,所以设计变更是最后的手段。

有什么想法吗?谢谢!

4 个答案:

答案 0 :(得分:9)

您必须继承您的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];
}

有关如何继承UINavigationBar的信息,您可以找到here

答案 1 :(得分:4)

@Andrei提供的代码在快速推送和弹出控制器时会导致iOS 7上的控制器堆栈不一致。系统本身将在推/弹动画之前和之后更改userInteractionEnabled属性。以下是我解决此问题的方法。

@interface DMNavigationBar ()

@property (nonatomic, assign) BOOL changingUserInteraction;
@property (nonatomic, assign) BOOL userInteractionChangedBySystem;

@end

@implementation DMNavigationBar

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if (self.userInteractionChangedBySystem && self.userInteractionEnabled == NO)
    {
        return [super hitTest:point withEvent:event];
    }

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

    return [super hitTest:point withEvent:event];
}

- (void)setUserInteractionEnabled:(BOOL)userInteractionEnabled
{
    if (!self.changingUserInteraction)
    {
        self.userInteractionChangedBySystem = YES;
    }
    else
    {
        self.userInteractionChangedBySystem = NO;
    }

    [super setUserInteractionEnabled:userInteractionEnabled];
}

@end

答案 2 :(得分:1)

如果同样的问题和上述答案都很好,他们指出了一个简洁的解决方案。

快速版本的答案相同:

  class APLVNavigationBar: UINavigationBar {
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
    if pointInside(point, withEvent: event){
        userInteractionEnabled = true
    }else{
        userInteractionEnabled = false
    }
    return super.hitTest(point, withEvent: event)
  }
}

答案 3 :(得分:-2)

我不认为这是问题所在,但你是否将按钮子视图带到了前面?

[self.view bringSubviewToFront:buttonView]