开发者

UINavigationItem Back Button touch area too large

开发者 https://www.devze.com 2023-01-19 10:32 出处:网络
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\").

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").

UINavigationItem Back Button touch area too large

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

UINavigationItem Back Button touch area too large

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号