UINavigationBar UIBarButtonItems much larger click area than required

和自甴很熟 提交于 2019-11-28 05:45:11

This is the only solution I found. Create a container of the custom button:

//Create a container for the button
UIView *buttonContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 55, 44)];

//Create a smaller button
UIButton *closeButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 55, 25)];
[closeButton setTitle:@"Cancel" forState:UIControlStateNormal];
//center the title
closeButton.titleEdgeInsets = UIEdgeInsetsMake(23, 0, 0, 0);

[buttonContainer addSubview:closeButton];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:buttonContainer];

I'm not 100% sure but maybe you can get the location of the touch via the UITouch class?

UIBarButtonItem doesn't extend UIResponder but UINavigationBar does!

So if you subclass UINavigationBar and use this subclass in your app, maybe you can catch the coordinates of the touch and check if they are ok to you and then decide to apply either the navigation bar action or your button action (by some custom redirection).

Short answer is... should shouldn't try and get rid of them. It's about ease of use. The navigation bar at the top tends to mean people tap lower than you may expect. Always leave that gap there, or have a sufficiently large hit area that the user stabbing their finger towards the middle of your "below the nav bar" item will avoid the dead area.

As far as I know, it is impossible to turn off. If you have other buttons on the navigation bar, those click-spaces will not collide, but if you have button directly beneath the nav bar with no space at all in between, you're out of luck. Consider a small padding in the header and its buttons as a solution.

Trying to work around the UINavigation Bar padding may run you into trouble when you submit to the app store. It would be easier to add the padding to your custom heading. As a "fat thumber" I have learned to appreciate the HIG.

Quite old question, but maybe a solution is helpful to others too...

I've created a UINavigationBar subclass, that overrides just one method: 'hitTest:withEvent:'. When hitTest:withEvent is called, it checks wether the event has happened inside the frame of the navigation bar (pointInside:withEvent:) or not. In case, the event has happened outside, the userInteractionEnabled flag is set to NO so the event will be ignored by the navigation bar and its subviews.

In my case, the navigation bar subclass is inserted via IB, but of course is is also possible to insert it via 'UINavigationController initWithNavigationBarClass:toolbarClass:'

Header:

@interface MMMasterNavigationBar : UINavigationBar

@end

Implementation:

@implementation MMMasterNavigationBar

/*
 hitTest:withEvent:

 The hit area in for navigation bar button items is enlarged by default.
 Other objects directly below the navigation bar doesn't receive tap events.
 We avoid the default enlarging of the tappable area by disabling userInteraction
 when the real tap is outside the navigation bar.

 */
-(UIView *)hitTest:(CGPoint)pPoint
         withEvent:(UIEvent *)pEvent {
    //FLog;

    if ([self pointInside:pPoint
                withEvent:pEvent]) {
        //NSLog(@"User interaction enabled");
        self.userInteractionEnabled = YES;

    } else {
        //NSLog(@"User interaction disabled");
        self.userInteractionEnabled = NO;
    }

    return [super hitTest:pPoint
                withEvent:pEvent];
}

@end

This can be done directly from a storyboard. Drag a UIView into each navigation item, set its background to clearColor, and size it. Drag a button into each UIView and size them to match.

    var buttonContainer:UIView = UIView()
    buttonContainer.frame = CGRectMake(0, 0, 32, 32)

    var imagess:UIImage = UIImage(named: "noti@2x.png")!

    var closeButton:UIButton = UIButton()
    closeButton.setImage(imagess, forState: UIControlState.Normal)
    closeButton.frame = CGRectMake(10, 5, 20, 20)
    closeButton.contentMode = UIViewContentMode.Center
    closeButton.titleEdgeInsets = UIEdgeInsetsMake(20, 0, 0, 0)

    buttonContainer.addSubview(closeButton)

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