UINavigationItem Back Button touch area too large

旧街凉风 提交于 2019-11-27 18:40:38

问题


On this following screenshot, if I click on "v" from "Available Kiosks" this is launching the action of the back button... (not with the second "a").

I don't understand why, I've nothing special in my code (this is the default backbutton handled by the navigation controller). I also have the same bug with another application I did but I never notice this on others applications.

Any Ideas ?

Thank you.


回答1:


That's not a bug, it does the same in Apple apps, and even on some (many / all ?) buttons. It's the behaviour of touch events on buttons : the area of the touch is larger than the button bounds.




回答2:


I needed to do the same thing and so I ended up swizzling the UINavigationBar touchesBegan:withEvent method and checking the y coordinate of the touch before calling the original method.
This means that when the touch was too close to a button that I was using under the Navigation I could cancel it.

Ex:The back button almost always captured the touch event instead of the "First" Button

Here is my category:

@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];
}

The swizzle implementation by Mike Ash from CocoaDev

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);
}

And the function calls to the swizzle function

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

I don't know if Apple is ok with this, it might be infringing on their UI guidelines, I will try to update the post if after I submit the app to the app store.



来源:https://stackoverflow.com/questions/3912831/uinavigationitem-back-button-touch-area-too-large

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!