UINavigationItem的返回按钮触摸区域过大

5
在以下屏幕截图中,如果我点击“可用亭子”中的“v”,这将启动后退按钮的操作...(而不是第二个“a”)。 alt text 我不明白为什么会这样,我的代码里没有特别之处(这是导航控制器处理的默认返回按钮)。 我还遇到了另一个应用程序出现相同的错误,但我从未在其他应用程序中注意到这一点。
有任何想法吗?
谢谢。

我现在也遇到了同样的问题,你找到解决方案了吗? - Andy Jacobs
不好意思...我发现这个漏洞存在于很多应用程序中... :o - William Remacle
2个回答

8

这不是一个 bug,在苹果应用程序中也是如此,甚至在一些(许多/全部?)按钮上也是如此。这是按钮触摸事件的行为:触摸区域大于按钮边界。


1

我需要做同样的事情,所以最终我对UINavigationBar的touchesBegan:withEvent方法进行了交换,并在调用原始方法之前检查了触摸的y坐标。
这意味着当触摸太靠近我在导航下使用的按钮时,我可以取消它。

例如:返回按钮几乎总是捕获触摸事件,而不是“First”按钮。 enter image description here

这是我的类别:

@implementation UINavigationBar (UINavigationBarCategory)
- (void)sTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
float maxY = 0;
for (UITouch *touch in touches) {
    float touchY = [touch locationInView:self].y;
    if ( [touch locationInView:self].y > maxY) maxY = touchY;
}

NSLog(@"swizzlelichious bar touchY %f", maxY);

if (maxY < 35 )
    [self sTouchesEnded:touches withEvent:event];
else 
    [self touchesCancelled:touches withEvent:event];
}
- (void)sTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
float maxY = 0;
for (UITouch *touch in touches) {
    float touchY = [touch locationInView:self].y;
    if ( [touch locationInView:self].y > maxY) maxY = touchY;
}

NSLog(@"swizzlelichious bar touchY %f", maxY);

if (maxY < 35 )
    [self sTouchesBegan:touches withEvent:event];
else 
    [self touchesCancelled:touches withEvent:event];
}

Mike Ash在CocoaDev上实现的Swizzle

void Swizzle(Class c, SEL orig, SEL new)
{
Method origMethod = class_getInstanceMethod(c, orig);
Method newMethod = class_getInstanceMethod(c, new);
if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
    class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
else
    method_exchangeImplementations(origMethod, newMethod);
}

还有对 swizzle 函数的调用

Swizzle([UINavigationBar class], @selector(touchesEnded:withEvent:), @selector(sTouchesEnded:withEvent:));
Swizzle([UINavigationBar class], @selector(touchesBegan:withEvent:), @selector(sTouchesBegan:withEvent:));

我不确定苹果公司是否会同意这样做,因为这可能会侵犯他们的用户界面指南,如果我提交应用程序到应用商店后有任何更新,我会尽快更新帖子。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接