UINavigationBar Touch

21,916

Solution 1

You can add a gesture recognizer to be a single tap to the title of the navigation controller. I found that in the navigationBar subviews, the title is the one at index 1, the left button's index is 0 and the right button's index is 2.

UITapGestureRecognizer *navSingleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(navSingleTap)];
navSingleTap.numberOfTapsRequired = 1;
[[self.navigationController.navigationBar.subviews objectAtIndex:1] setUserInteractionEnabled:YES];
[[self.navigationController.navigationBar.subviews objectAtIndex:1] addGestureRecognizer:navSingleTap];

and then implement the following somewhere in your implementation.

-(void)navSingleTap

So you can use this for a single tap, or you can implement any gesture recognizer you want on that title.

Solution 2

None of the other answers worked well for me. Rather than add a gesture to an existing subview of the navigationBar, or replace the titleView, I simply added a clear UIView covering a good portion of the navigationBar...

- (void) setupNavbarGestureRecognizer {
    // recognise taps on navigation bar to hide
    UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showHideNavbar)];
    gestureRecognizer.numberOfTapsRequired = 1;
    // create a view which covers most of the tap bar to
    // manage the gestures - if we use the navigation bar
    // it interferes with the nav buttons
    CGRect frame = CGRectMake(self.view.frame.size.width/4, 0, self.view.frame.size.width/2, 44);
    UIView *navBarTapView = [[UIView alloc] initWithFrame:frame];
    [self.navigationController.navigationBar addSubview:navBarTapView];
    navBarTapView.backgroundColor = [UIColor clearColor];
    [navBarTapView setUserInteractionEnabled:YES];
    [navBarTapView addGestureRecognizer:gestureRecognizer];
}

Solution 3

The UINavigationItem class reference has a titleView property, which you can set to your custom UIView.

In other words, make a subclass of UIView with your touch handlers, and then when you push your navigation item, set that item's titleView property to an instance of your subclass.

Solution 4

This is the simplest and easiest solution in Swift, just copy/paste and fill in the blanks:

let navTapGesture = UITapGestureRecognizer(target: <#T##AnyObject?#>, action: <#T##Selector#>)
navigationItem.titleView.userInteractionEnabled = true
navigationItem.titleView.addGestureRecognizer(navTapGesture)

Be sure to set the userInteractionEnabled to true on the titleView, its off by default.

Solution 5

One of the possible options: (Use UILabel)

UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doSomething:)];
UILabel * titleView = [UILabel new];
titleView.text = @"Test";
[titleView sizeToFit];
titleView.userInteractionEnabled = YES;
[titleView addGestureRecognizer:tapGesture];

self.navigationItem.titleView = titleView;
Share:
21,916
mootymoots
Author by

mootymoots

Updated on March 21, 2020

Comments

  • mootymoots
    mootymoots about 4 years

    I would like to fire an event on touch when a user taps the title of the navigation bar of one of my views.

    I'm at a bit of a loss on whether I can access the view of the title of the UINavigationBar in order to wire up a touch event to it.

    Is this even possible?

  • mootymoots
    mootymoots over 14 years
    Thanks, but then how do I act on that touch, for example - how can I call a method in my overall view controller if the titleView is touched?
  • mootymoots
    mootymoots over 14 years
    Also, with this approach, my title attribute is lost. Could you explain further? I've added a touchesBegan handler with a simple NSLog(@"touched"); but it does nothing when the titleView is hit. I'm creating an instance of the subclass, and assigning it to the instance of the view I'm about to push, ie view.navigationItem.titleView = mySubclass;
  • Alex Reynolds
    Alex Reynolds over 14 years
    Your custom UIView can have many properties, including a UILabel to replace the title, and a UIViewController property for the "parent" view controller, which you set when you create an instance of your custom view. Also check that your view has a frame of sufficient size.
  • Sam Joseph
    Sam Joseph almost 12 years
    this is the only one that worked for me so far as well, although I seemed to need to add:[self.navigationController.navigationBar setUserInteractionEnabled:YES]; and I still have inteference with buttons due to variable button names as part of the rest of my application - with there was a consistent way of just attaching touchability to the title (which in my case is a UIImageView)
  • Sam Joseph
    Sam Joseph almost 12 years
    aha, I finally got just the title being touchable - here's how: pastebin.com/eFwTShhz
  • Rik Smith-Unna
    Rik Smith-Unna almost 12 years
    @SamJoseph you should post that solution as an answer
  • zekel
    zekel almost 12 years
    This works if you don't want to set a custom titleView. (Which I didn't.)
  • Adam Carter
    Adam Carter over 10 years
    Is it possible to set a tint colour so it looks a bit more like a button? I've tried setTintColor and setTintAdjustmentMode, but neither work
  • James
    James about 10 years
    This definitely seems to be the most valid answer. Thanks~
  • James
    James about 10 years
    I've found that I had to put this in the viewDidLoad method to get it to work if I navigate deeper into the storyboard and come back, otherwise all of my navigation bar items were activating it after that.
  • Jenny
    Jenny about 9 years
    Hi ~ @phmagic, I fond that it's only work for topViewController, not secondViewController.Do you know why is that? Does anyone face the same issue?
  • Ken M. Haggerty
    Ken M. Haggerty about 9 years
    This answer worked for me by overwriting -[gestureRecognizerShouldBegin] in a category on UINavigationBar and importing that category into my view controller.
  • pixelrevision
    pixelrevision about 8 years
    This one is nice as it does not mess with things like the back button.
  • Zsolt Szatmari
    Zsolt Szatmari about 8 years
    While creating a view for this seems to be PITA, but on the other hand, doing this instead is a hack, and might break with future iOS versions. Don't do this if you care about your code.
  • Yogesh Patel
    Yogesh Patel over 2 years
    Hello, is it fine if we don't remov the gesture?
  • Beau Nouvelle
    Beau Nouvelle over 2 years
    Sure. Should be fine.