UINavigationBar Touch
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;
mootymoots
Updated on March 21, 2020Comments
-
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 over 14 yearsThanks, 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 over 14 yearsAlso, 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 over 14 yearsYour custom
UIView
can have many properties, including aUILabel
to replace the title, and aUIViewController
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 almost 12 yearsthis 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 almost 12 yearsaha, I finally got just the title being touchable - here's how: pastebin.com/eFwTShhz
-
Rik Smith-Unna almost 12 years@SamJoseph you should post that solution as an answer
-
zekel almost 12 yearsThis works if you don't want to set a custom titleView. (Which I didn't.)
-
Adam Carter over 10 yearsIs it possible to set a tint colour so it looks a bit more like a button? I've tried
setTintColor
andsetTintAdjustmentMode
, but neither work -
James about 10 yearsThis definitely seems to be the most valid answer. Thanks~
-
James about 10 yearsI'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 about 9 yearsHi ~ @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 about 9 yearsThis answer worked for me by overwriting
-[gestureRecognizerShouldBegin]
in a category on UINavigationBar and importing that category into my view controller. -
pixelrevision about 8 yearsThis one is nice as it does not mess with things like the back button.
-
Zsolt Szatmari about 8 yearsWhile 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 over 2 yearsHello, is it fine if we don't remov the gesture?
-
Beau Nouvelle over 2 yearsSure. Should be fine.