kevboh kevboh - 2 months ago 21
iOS Question

detect long press on UINavigationItem's back button

I want to add functionality to my back buttons through my UINavigationController-based app where long-pressing the back button will pop to root. However, I can't figure out where to attach the gesture recognizer. Do I subclass UINavigationBar and try and detect if the long press is in the left button region?

I've heard of people adding similar functionality before. Anyone have any ideas?

Answer

I believe UIGestureRecognizers can only be added to UIViews and subclasses of UIViews.

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIView_Class/UIView/UIView.html

The back button is a UIBarButtonItem that descends from NSObject. Therefore, you won't be able to attach a gesture recognizer to a standard back button using

UILongPressGestureRecognizer *longPressGesture =
            [[[UILongPressGestureRecognizer alloc]
              initWithTarget:self action:@selector(longPress:)] autorelease];

[self.navigationItem.backBarButtonItem addGestureRecognizer:longPressGesture];

You can however add a custom view to a UIBarButtonItem. A custom view could just as easily be a UIView, UIButton, UILabel, etc.

Example:

UIView *myTransparentGestureView = [[UIView alloc] initWithFrame:CGRectMake(0,0,40,30)];
[myTransparentGestureView addGestureRecognizer:longPressGesture];
[self.navigationItem.backBarButtonItem setCustomView:myTransparentGestureView];
// Or you could set it like this
// self.navigationItem.backBarButtonItem.customView = myTransparentGestureView;
[myTransparentGestureView release];

You have to be careful however, since setting properties on backBarButtonItem applies to the next view that you push. So if you have view A that pushes to view B and you want the gesture to be recognized when you tap back in view B. You must set it up in view A.