Here's my solution:
In appDelegate (the "owner" of the nav bar in my app), In applicationDidFinishLaunchingWithOptions:
Get the nav bar view and add the gesture recognizer to the whole view:
// Get the nav bar view
UINavigationBar *myNavBar = nil;
for (UIView *view in [self.window.rootViewController.view subviews]) {
if ([view isKindOfClass:[UINavigationBar class]]) {
NSLog(@"Found Nav Bar!!!");
myNavBar = (UINavigationBar *)view;
}
}
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self
action:@selector(backButtonLongPress:)];
[myNavBar addGestureRecognizer:longPress];
NSLog(@"Gesture Recognizer Added.");
Then in appDelegate, in -(void) backButtonLongPress:(id) sender
Check to see if the gesture occurs within the frame of the back button:
if ([sender state] == UIGestureRecognizerStateBegan) {
// Get the nav bar view
UINavigationBar *myNavBar = nil;
for (UIView *view in [self.window.rootViewController.view subviews]) {
if ([view isKindOfClass:[UINavigationBar class]]) {
NSLog(@"Found Nav Bar!!!");
myNavBar = (UINavigationBar *)view;
}
}
// Get the back button view
UIView *backButtonView = nil;
for (UIView *view in [myNavBar subviews]) {
if ([[[view class] description] isEqualToString:@"UINavigationItemButtonView"]) {
backButtonView = view;
NSLog(@"Found It: %@", backButtonView);
NSLog(@"Back Button View Frame: %f, %f; %f, %f", backButtonView.frame.origin.x, backButtonView.frame.origin.y, backButtonView.frame.size.width, backButtonView.frame.size.height);
}
}
CGPoint longPressPoint = [sender locationInView:myNavBar];
NSLog(@"Touch is in back button: %@", CGRectContainsPoint(backButtonView.frame, longPressPoint) ? @"YES" : @"NO");
if (CGRectContainsPoint(backButtonView.frame, longPressPoint)) {
// Place your action here
}
// Do nothing if outside the back button frame
}