4

I know some have already asked the question but so far, the answers are not really specific.

Apparently apple have made the click area of the NavigationBar larger than it really is, but I don't think it's supposed to be that large.

In my app, there is a TableView right underneath the NavBar and you can click all the way down to half of the first cell to trigger the event of the rightBarButtonItem. the button is instanced like this:

    UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(editTable)];
 [[self navigationItem] setRightBarButtonItem:editButton];

"self" is the root ViewController of a NavigationController.

As you could imagine, it's a problem since the cells are selectable to push another ViewController.

I managed to go around the problem by making the cells' height bigger but I'd rather have them at the regular size.

I'm sure I'm not the only one with this case of scenario. Thanks in advance.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
DEIONaLiMs
  • 162
  • 1
  • 11

6 Answers6

8
UIButton *menuButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
[menuButton addTarget:self action:@selector(revealMenu:) forControlEvents:UIControlEventTouchUpInside];
[menuButton setImage:[UIImage imageNamed:@"menuIcon"] forState:UIControlStateNormal];
UIView *menuButtonContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
[menuButtonContainer addSubview:menuButton];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:menuButtonContainer];

This perfectly worked for me....

nsgulliver
  • 12,655
  • 23
  • 43
  • 64
iosDeveloper
  • 169
  • 2
  • 8
0

The other answer here from iosDeveloper about putting a container view around the button can help reduce the size of the clickable area on the left and right of the button, but doesn't help with the issue I had where you would activate the button clicking below the navigation bar.

After hours of searching several different SO threads and trying various things, I finally found my answer to this issue here: https://stackoverflow.com/a/10597699/1289240

Community
  • 1
  • 1
Greg G
  • 461
  • 4
  • 14
0

Since i use a transparent toolbar and tint the UIBarButtonItem, I couldn't use a custom view as I would need to set tint, width/height, rounded corners to make it similar to UIBarButtonItem look

I therefore use a invisible button which I add to my items to resolve this issue. and events are trappped there

in @interface UIBarButtonItem (ImageButton)

+ (UIBarButtonItem*) invisibleButtonForTransparentBar {
   static UIBarButtonItem* fakeBtn = nil;
   if (!fakeBtn) {
       fakeBtn = [[UIBarButtonItem alloc] initWithCustomView:[[UIView alloc] init]];
   }
   return fakeBtn; 
}

in View Controller:

[self.viewToolbar setItems: @[flexSpace,
   [UIBarButtonItem fakeLastButtonForTransparentBar], 
   self.btnTrackUser,
   self.btnMapConfig,
   [UIBarButtonItem fakeLastButtonForTransparentBar],
   flexSpace] ];
altagir
  • 640
  • 8
  • 18
0

You can't do much about the touch area. It's all based on how much finger area is picked up by the display. You can calculate size of touch area (warning: undocumented api) but intercepting touch events and calling a method to correct for fat finger syndrome seems a bit over-the-top.

Basic process is:

  1. You touch screen
  2. Change of capacitance is measured in a unique, individualized portion of the screen and sent to hardware/software to interpret (just as an aside, Apple's patent states as many as 15 touches can be tracked at once.. 10 fingers, two palms, and 3 others in case you ever make an iPhone "Twister" game)
  3. Software interprets gradients in capacitance on screen and identifies touch boundaries
  4. Software calculates centroid of touch based on the average capacitance magnitude for each pixel or point in the region
  5. Software sends coordinates of touch boundary locations into application
  6. Your app interprets as a touch event, it gets sent along the responder chain, and (hopefully) the user see's the touch on the screen
Community
  • 1
  • 1
iwasrobbed
  • 46,496
  • 21
  • 150
  • 195
  • 2
    I find it a little weird though. Being able to clic all the way down to half of the 1st cell and trigger the rightBarButton is not really helping fat fingers because fat fingers only have half of this cell to trigger it. Anyway, thanks for the info. – DEIONaLiMs Jul 29 '10 at 08:08
  • Yeah it's not a perfect system, but there are situations like this everywhere that you just have to find small workarounds for. – iwasrobbed Jul 29 '10 at 11:13
  • Actually this still does not make sense... If this was true it would work the same for all UI elements? I have a detail disclosure button just under my UIBarButtonItem and the UIBarButtonItem's touch area is the only one that is abnormally big... so big that it actually overlaps some of my detail disclosure button. – Marius Mar 04 '11 at 22:46
  • 1
    @Marius: You mean the UIBarButtonItem that is at the top of the screen... where it is much more difficult to get an even pressure gradient when you tap down? Think about it for a second: when you press on the screen near the screen edges, you are pressing in an area that is well supported so the capacitive gradient will be uneven moreso in that area versus pressing in the center of the screen. Everything I wrote in my answer above is taken directly from Apple's patent. If you're going to downvote someone, make sure it's based on facts and not opinions. – iwasrobbed Mar 04 '11 at 23:51
  • 8
    Still, it overlaps *OVERLAPS* other buttons which are also in the same area covered in the patent. It is a ridiculously large area and is not consistent. The question posed asked for a solution (and I did some searches and there are), and all you did was reiterate why the person is having a problem and is not really an answer. Sorry, but for people searching for a solution to this and coming here hitting your answer is just a waste of time. – Marius Mar 15 '11 at 14:11
  • 4
    @Marius: Rather than insulting other people's answers, post your own. This is a community for sharing knowledge, not a pissing contest. – iwasrobbed Mar 15 '11 at 17:54
0

We are unable to reduce the default uibarbuttonitem size. The idea is to make a uibutton, add to a uiview , then to uibarbuttonitem's custom view. The size of the uiview containing uibutton will be the click area of the uibarbutton.

Here is my code:

self.navigationController?.navigationBarHidden =  false

    let navigationBar = UINavigationBar(frame: CGRectMake(0, 0, self.view.frame.size.width, 64)) // Offset by 20 pixels vertically to take the status bar into account

    navigationBar.backgroundColor = UIColor.blueColor()
    navigationBar.delegate = self;

    // Create a navigation item with a title
    let navigationItem = UINavigationItem()

    //menu button
    let menubutton: UIButton = UIButton(frame: CGRectMake(0, 0, 30, 30))
    menubutton.setImage(UIImage(named: "menu"), forState: UIControlState.Normal)
    menubutton.addTarget(self, action: "btn_clicked", forControlEvents: UIControlEvents.TouchUpInside)

    //menu button custom view
    let leftView = UIView(frame: CGRectMake(0,0,30,30))
    leftView.addSubview(menubutton)

    //left uibarbutton
    let leftItem:UIBarButtonItem = UIBarButtonItem(customView: leftView)
    navigationItem.leftBarButtonItem = leftItem


    //searchButton
    let searchbutton: UIButton = UIButton()
    searchbutton.setImage(UIImage(named: "search1x"), forState: UIControlState.Normal)
    searchbutton.frame = CGRectMake(0, 0, 30, 30)
    searchbutton.addTarget(self, action: "btn_clicked", forControlEvents: UIControlEvents.TouchUpInside)


    //menu button custom view
    let rightView = UIView(frame: CGRectMake(0,0,30,30))
    rightView.addSubview(searchbutton)

    //right uibarbutton
    let rightItem:UIBarButtonItem = UIBarButtonItem(customView: rightView)
    navigationItem.rightBarButtonItem = rightItem

    // Assign the navigation item to the navigation bar
    navigationBar.items = [navigationItem]

    // Make the navigation bar a subview of the current view controller
    self.view.addSubview(navigationBar)

Note: Ex:- menu button is a UIButton and added to leftView. The leftItem is a UIBarButtonItem and is added to leftBarButtonItem of the navigationBar. The leftView is added as the custom view of leftItem. So, the click area of leftBarButtonItem of the navigationBar is the frame of leftView. i.e., frame: CGRectMake(0,0,30,30).

Alvin George
  • 14,148
  • 92
  • 64
0

All I can offer is to create UIBarButtonItem with custom view

let view = CustomView()
let itemButton = UIBarButtonItem(customView: view)

Then override this view's touchesEnded

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesEnded(touches, with: event)
    if touches.count == 1,
        let touch = touches.first {
        let touchPoint = touch.location(in: self)
        if bounds.contains(touchPoint) {
            someAction()
        }
    }
}

Don't forget to make it user interaction enabled somewhere in the init isUserInteractionEnabled = true.