UINavigationBar Touch

Viewed 22026

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?

9 Answers

The solution I found is a button, I use the following (but I don't know how "legal" it is):

UIButton *titleLabelButton = [UIButton buttonWithType:UIButtonTypeCustom];
[titleLabelButton setTitle:@"myTitle" forState:UIControlStateNormal];
titleLabelButton.frame = CGRectMake(0, 0, 70, 44);
titleLabelButton.font = [UIFont boldSystemFontOfSize:16];
[titleLabelButton addTarget:self action:@selector(didTapTitleView:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.titleView = titleLabelButton;

Put that bit of code where ever you set your title. Then elsewhere I had this to test:

- (IBAction)didTapTitleView:(id) sender
{
    NSLog(@"Title tap");
}

which logged "Title tap" on the console!

The way I've gone about this may be completely wrong, but might give you an idea on what you can look in to. It's certainly helped me out! There's probably a better way of doing it though.

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.

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.

Building on this answer and this one, I went with the below "functional" approach, I am not sure it is anymore readable, but I prefer it over breaking out of a loop.

    if let navTitle = self.navigationController?.navigationBar.subviews.first(where: {$0.subviews.first is UILabel}) {
        let gesture = UITapGestureRecognizer(target: self, action: action)
        gesture.numberOfTapsRequired = numberOfTapsRequired
        navTitle.isUserInteractionEnabled = true
        navTitle.addGestureRecognizer(gesture)
    }
Related