Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable back gesture in iOS 7 for only one view

Tags:

ios7

back

gesture

I am trying to disable the back gesture for my view controller using the following set of code.

In FirstViewController.m, I'm setting the delegate of interactivePopGestureRecognizer

- (void) viewWillLoad {

    // Other stuff..
    self.navigationController.interactivePopGestureRecognizer.delegate = self;
}

And then implementing the <UIGestureRecognizerDelegate> method and returning NO.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {

     return NO;
}

And in dealloc I'm setting the delegate to nil. (I have read somewhere that in iOS 7, you have to manually set the delegates to nil)

- (void)dealloc {

    self.navigationController.delegate = nil;
    self.navigationController.interactivePopGestureRecognizer.delegate = nil;
}

This works in the FirstViewController. But when I push SecondViewController to this, the gesture does not work on that either. How can I disable the gesture in FirstViewController only?

Also when I pop FirstViewController to go to RootViewController and then try to push FirstViewController again, I get the object deallocated error :

[FirstViewController gestureRecognizer:shouldReceiveTouch:]: message sent to deallocated instance 0x14ed0280

Why else do I need to do other than setting the delegates to nil? Or am I setting it in the wrong place?

like image 539
Rohith Nandakumar Avatar asked Oct 01 '13 05:10

Rohith Nandakumar


2 Answers

Try the below untested code in your FirstViewController :

-(void) viewWillAppear:(BOOL)animated 
{
    [super viewWillAppear:animated];
    self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}

-(void) viewWillDisappear:(BOOL)animated 
{
    [super viewWillDisappear:animated];
    self.navigationController.interactivePopGestureRecognizer.enabled = YES;
}
like image 146
Tarek Hallak Avatar answered Sep 20 '22 18:09

Tarek Hallak


I originally put these answers into a comment below the accepted answer, but I feel this needs to be said as an answer to get more visibility.

More often than not, you will find that the accepted answer does not work. This is because viewWillAppear: can be called before the view is added to a navigation controller's view hierarchy, and so self.navigationController is going to be nil. Because of this, the interactivePopGestureRecognizer may not be disabled in some cases. You're better off calling it in viewDidAppear: instead.

Here's code that will work (assuming your view controller is correctly added to a navigation controller's view hierarchy):

Objective-C

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [[[self navigationController] interactivePopGestureRecognizer] setEnabled:NO];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[[self navigationController] interactivePopGestureRecognizer] setEnabled:YES];
}

Swift

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    navigationController?.interactivePopGestureRecognizer?.isEnabled = false
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    navigationController?.interactivePopGestureRecognizer?.isEnabled = true
}
like image 34
John Rogers Avatar answered Sep 22 '22 18:09

John Rogers