SWRevealViewController: Remove interaction on frontview when rearview is revealed

I've recently come up with a solution that I wanted to share (sorry if it's 2 months late).

To disable user interaction on the Front View while the Menu is open, I added the following codes on my MenuViewController:

on viewWillAppear:

[self.revealViewController.frontViewController.view setUserInteractionEnabled:NO];

and on viewWillDisappear:

[self.revealViewController.frontViewController.view setUserInteractionEnabled:YES];

This will disable all user interactions on the Front View Controller, which means that the slide / tap gestures to CLOSE the menu will also be DISABLED.

Now, I have created a ParentViewController and made all the view controllers (the menu items) a subclass of it.

on my viewDidLoad, I put the following codes:

SWRevealViewController *revealController = [self revealViewController];
[revealController panGestureRecognizer];
[revealController tapGestureRecognizer];

If you run your app at this point, it would appear that the Tap Gesture works (a tap on the Front View will close the Menu), but NOT the Pan Gesture. I'm not sure why this is so, but in order to enable the slide gesture to CLOSE your menu, add the following code in your MenuViewController:

on viewWillAppear:

[self.revealViewController.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];

To summarize, here's what you need:

On your MenuViewController:

-(void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [self.revealViewController.frontViewController.view setUserInteractionEnabled:NO];
    [self.revealViewController.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
}

-(void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];

    [self.revealViewController.frontViewController.view setUserInteractionEnabled:YES];
}

And on your menu items' view controller (you can make a ParentViewController for all of them):

-(void)viewDidLoad {
    [super viewDidLoad];

    SWRevealViewController *revealController = [self revealViewController];
    [revealController panGestureRecognizer];
    [revealController tapGestureRecognizer];
}

Hope this helps!


I have used another approach to achieve the same outcome not sure if it helps.

Assign SWRevealViewControllerDelegate to AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    SWRevealViewController* reveal = (SWRevealViewController*)self.window.rootViewController;
    reveal.delegate = self;

    // other bootstrapping code
}

and then in the delegate method -(void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position as below:

-(void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position
{
    if(position == FrontViewPositionLeft){
        [revealController.frontViewController.view setUserInteractionEnabled:YES];
        [revealController.frontViewController.revealViewController tapGestureRecognizer];
    }else{
        [revealController.frontViewController.view setUserInteractionEnabled:NO];
    }
}

UPDATED: added this line [revealController.frontViewController.revealViewController tapGestureRecognizer] to close the revealed controller when tap on frontviewcontroller


Swift version to @hardluckbaby answer:

In MenuViewController(Rear view controller):

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    self.revealViewController().frontViewController.view.userInteractionEnabled = false
    self.revealViewController().view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)

    self.revealViewController().frontViewController.view.userInteractionEnabled = true
}

In FrontViewController(You can make a ParentViewController for all of your front view controllers as @hardluckbaby said):

override func viewDidLoad() {
    super.viewDidLoad()

    if let revealController = self.revealViewController() {
        revealController.panGestureRecognizer()
        revealController.tapGestureRecognizer()
    }
}