Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SWRevealViewController close rear view when tapping front view

I am using SWRevealViewController in order to implement a side nav menu in my app. I would like to make it so that the front view cannot be interacted with when the rear view is opened, except that when the user taps the front view, the rear view will close and the front view can be interacted with again. I have these two SWRevealViewController delegate methods that currently remove interaction from the front view.

- (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:    (FrontViewPosition)position {
    if(position == FrontViewPositionLeft) {
        self.view.userInteractionEnabled = YES;
    } else {
        self.view.userInteractionEnabled = NO;
    }
}

- (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:    (FrontViewPosition)position {
    if(position == FrontViewPositionLeft) {
        self.view.userInteractionEnabled = YES;
    } else {
        self.view.userInteractionEnabled = NO;
    }
}

However this doesn't cause the rear view to close when the front view is tapped. Any help would be greatly appreciated, thanks!

like image 374
shadowarcher Avatar asked Mar 08 '14 22:03

shadowarcher


4 Answers

If you are using SWIFT, you can do something like this, in your frontViewController:

override func viewDidLoad() {
    super.viewDidLoad()

    if self.revealViewController() != nil {

        self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
        self.view.addGestureRecognizer(self.revealViewController().tapGestureRecognizer())
    }

}

Code works for TAP and PAN gesture.

like image 126
Adam Studenic Avatar answered Oct 18 '22 20:10

Adam Studenic


In ViewDidLoad of your frontViewController you need to add a UITapGestureRecognizer

SWRevealViewController *revealController = [self revealViewController];
UITapGestureRecognizer *tap = [revealController tapGestureRecognizer];
tap.delegate = self;

[myView addGestureRecognizer:tap];

This should cause the rear view to close when the front view is tapped which is SWRevealViewController's default behaviour.

like image 44
Nick Avatar answered Oct 18 '22 19:10

Nick


EDIT: Change UIView's autoresizingMask to suit Swift 2, thanks to Marroc's comment

This is Swift-SWRevealViewController 2.x version of @avdyushin's answer:

func revealController(revealController: SWRevealViewController!, willMoveToPosition position: FrontViewPosition) {
    let tagId = 4207868622

    if revealController.frontViewPosition == FrontViewPosition.Right {
        let lock = self.view.viewWithTag(tagId)
        UIView.animateWithDuration(0.25, animations: {
                lock?.alpha = 0
            }, completion: {(finished: Bool) in
                lock?.removeFromSuperview()
            }
        )
        lock?.removeFromSuperview()
    } else if revealController.frontViewPosition == FrontViewPosition.Left {
        let lock = UIView(frame: self.view.bounds)
        lock.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
        lock.tag = tagId
        lock.alpha = 0
        lock.backgroundColor = UIColor.blackColor()
        lock.addGestureRecognizer(UITapGestureRecognizer(target: self.revealViewController(), action: "revealToggle:"))
        self.view.addSubview(lock)
        UIView.animateWithDuration(0.75, animations: {
                lock.alpha = 0.333
            }
        )
    }
}
like image 31
mixth Avatar answered Oct 18 '22 19:10

mixth


  1. Subclass of SWRevealViewController.
  2. Implement revealController:willMoveToPosition: of SWRevealViewControllerDelegate.
  3. Set full screen view on front view controller to override all touches.
  4. Add tap gesture recognizer to hide menu.

Sample with nice animation:

- (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position;
{
    static NSInteger tagLockView = 4207868622;
    if (revealController.frontViewPosition == FrontViewPositionRight) {
        UIView *lock = [self.frontViewController.view viewWithTag:tagLockView];
        [UIView animateWithDuration:0.25 animations:^{
            lock.alpha = 0;
        } completion:^(BOOL finished) {
            [lock removeFromSuperview];
        }];
    } else if (revealController.frontViewPosition == FrontViewPositionLeft) {
        UIView *lock = [[UIView alloc] initWithFrame:self.frontViewController.view.bounds];
        lock.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        lock.tag = tagLockView;
        lock.backgroundColor = [UIColor blackColor];
        lock.alpha = 0;
        [lock addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(revealToggle:)]];
        [self.frontViewController.view addSubview:lock];
        [UIView animateWithDuration:0.75 animations:^{
            lock.alpha = 0.333;
        }];
    }
}

This solution for old version 1.x SWRevealViewController.

like image 40
avdyushin Avatar answered Oct 18 '22 20:10

avdyushin