UINavigationItem Back Button touch area too large
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 (th开发者_StackOverflowis 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.
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.
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.
精彩评论