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
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.
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];
}
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)
}