SWRevealViewController在点击前视图时closures后视图

我正在使用SWRevealViewController为了在我的应用程序中实现一个侧面的菜单。 我想这样做是为了使前视图不能与后视图打开时相互作用,除了当用户敲击前视图时,后视图将closures,并且前视图可以再次与之交互。 我有这两个SWRevealViewController委托方法,当前从前视图中删除交互。

 - (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; } } 

但是,当前视图被轻敲时,这不会导致后视图closures。 任何帮助将不胜感激,谢谢!

如果您正在使用SWIFT,则可以在frontViewController中执行以下操作:

 override func viewDidLoad() { super.viewDidLoad() if self.revealViewController() != nil { self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer()) self.view.addGestureRecognizer(self.revealViewController().tapGestureRecognizer()) } } 

代码适用于TAP和PAN手势。

在你的frontViewController的ViewDidLoad中,你需要添加一个UITapGestureRecognizer

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

这应该导致后视图closures,当前视图是SWRevealViewController的默认行为。

编辑:更改UIView的autoresizingMask适合Swift 2,感谢Marroc的评论

这是@ avdyushin的Swift-SWRevealViewController 2.x版本的答案:

 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 } ) } } 
  1. SWRevealViewController子类。
  2. 实现revealController:willMoveToPosition: SWRevealViewControllerDelegate
  3. 在前视图控制器上设置全屏视图以覆盖所有触摸。
  4. 添加点击手势识别器来隐藏菜单。

有很好的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; }]; } } 

此解决scheme适用于旧版本1.x的SWRevealViewController。

考虑这个简单的解决scheme,完美的作品

 private let DimmingViewTag = 10001 extension UIViewController: SWRevealViewControllerDelegate { func setupMenuGestureRecognizer() { revealViewController().delegate = self view.addGestureRecognizer(revealViewController().panGestureRecognizer()) view.addGestureRecognizer(revealViewController().tapGestureRecognizer()) } //MARK: - SWRevealViewControllerDelegate public func revealController(revealController: SWRevealViewController!, didMoveToPosition position: FrontViewPosition) { if case .Right = position { let dimmingView = UIView(frame: view.frame) dimmingView.tag = DimmingViewTag view.addSubview(dimmingView) view.bringSubviewToFront(dimmingView) } else { view.viewWithTag(DimmingViewTag)?.removeFromSuperview() } } } 

UIViewController简单用法:

 override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) setupMenuGestureRecognizer() } 

把下面的代码放在菜单视图控制器上,它对我来说很有用

 @interface SidebarTableViewController() { UIView* coverView; } - (void)viewWillDisappear:(BOOL)animated { [coverView removeFromSuperview]; //[self.revealViewController.frontViewController.view setUserInteractionEnabled:YES]; // get your window screen size } - (void)viewWillAppear:(BOOL)animated { // get your window screen size CGRect screenRect = [[UIScreen mainScreen] bounds]; //create a new view with the same size coverView = [[UIView alloc] initWithFrame:screenRect]; // change the background color to black and the opacity to 0.6 coverView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6]; // add this new view to your main view [self.revealViewController.frontViewController.view addSubview:coverView]; // [self.revealViewController.frontViewController.view setUserInteractionEnabled:NO]; } 

感谢mixth和avdyushin的帮助。 下面是从那里得到的Swift 4版本的答案,以节省你的几个小时:

 extension UIViewController: SWRevealViewControllerDelegate { func setupMenuGestureRecognizer() { revealViewController().delegate = self view.addGestureRecognizer(revealViewController().panGestureRecognizer()) view.addGestureRecognizer(revealViewController().tapGestureRecognizer()) } //MARK: - SWRevealViewControllerDelegate public func revealController(_ revealController: SWRevealViewController!, willMoveTo position: FrontViewPosition) { let tagId = 112151 print("revealController delegate called") if revealController.frontViewPosition == FrontViewPosition.right { let lock = self.view.viewWithTag(tagId) UIView.animate(withDuration: 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.black lock.addGestureRecognizer(UITapGestureRecognizer(target: self.revealViewController(), action: #selector(SWRevealViewController.revealToggle(_:)))) self.view.addSubview(lock) UIView.animate(withDuration: 0.75, animations: { lock.alpha = 0.333 } ) } } } 

现在从后视控制器的viewDidLoad调用setupMenuGestureRecognizer函数。

或者,您也可以直接将SWRevealViewControllerDelegate应用于后视控制器类,并在类中使用SWRevealViewControllerDelegate函数。

我使用tapGestureRecognizer,但仍然有一些问题。 我试过这个,工作很棒!

定义类:

 @interface IgnoreView : UIView @property (nonatomic, assign) BOOL shouldAllTouchesBeForMe; @end 

实行:

 @implementation IgnoreView - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { if( self.shouldAllTouchesBeForMe ){ return self; } return [super hitTest:point withEvent:event]; } @end 

然后在类IgnoreView的Interface Builder中创buildView类

在您的ViewController中,然后,执行:

in-viewDidLoad

 self.revealViewController.delegate = self; [self.view addGestureRecognizer:self.revealViewController.tapGestureRecognizer]; 

您的视图控制器中的工具也:

 - (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position { IgnoreView *i = (id)self.view; i.shouldAllTouchesBeForMe = position == FrontViewPositionRight; } 

你们都准备好了!

在你的菜单视图控制器上 ,添加这个:

 -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.revealViewController.frontViewController.view setUserInteractionEnabled:NO]; } -(void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [self.revealViewController.frontViewController.view setUserInteractionEnabled:YES]; } 

然后在你的菜单项视图控制器上 ,在viewDidLoad上添加这个:

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

在这里查看我的答案。 它解决了前视交互问题(加上滑动手势)。