简体   繁体   English

SWRevealViewController:显示后视时移除前视上的交互

[英]SWRevealViewController: Remove interaction on frontview when rearview is revealed

I need to disable user interaction on front view when rear view is revealed.当显示后视图时,我需要禁用前视图上的用户交互。 Found some others asking the same thing but can't really understand where or how to implement the code that I've seen.发现其他一些人提出了同样的问题,但无法真正理解在哪里或如何实现我所看到的代码。

Ex: I found this code from link ,例如:我从链接中找到了这个代码,

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

Also found few other links还发现了一些其他链接

I have this code, but not really sure about the correct place to insert this code.我有这段代码,但不太确定插入这段代码的正确位置。 I've tried adding it in my front/rear views and also in the SWRevealViewController method with no success我尝试将它添加到我的前/后视图以及SWRevealViewController方法中,但没有成功

Appreciate if someone can point me in the right direction.感谢有人能指出我正确的方向。

I've recently come up with a solution that I wanted to share (sorry if it's 2 months late).我最近想出了一个我想分享的解决方案(抱歉,如果晚了 2 个月)。

To disable user interaction on the Front View while the Menu is open, I added the following codes on my MenuViewController :要在菜单打开时禁用前视图上的用户交互,我在MenuViewController上添加了以下代码:

on viewWillAppear :viewWillAppear 上

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

and on viewWillDisappear :并在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.现在,我创建了一个ParentViewController并使所有视图控制器(菜单项)成为它的子类。

on my viewDidLoad , I put the following codes:在我的viewDidLoad 上,我输入了以下代码:

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.如果此时您运行您的应用程序,看起来 Tap Gesture 有效(点击 Front View 将关闭菜单),但不是 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 :我不确定为什么会这样,但是为了启用滑动手势来关闭菜单,请在MenuViewController 中添加以下代码:

on viewWillAppear :viewWillAppear 上

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

To summarize, here's what you need:总而言之,这是您需要的:

On your MenuViewController :在您的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):在您的菜单项的视图控制器上(您可以为所有菜单项创建一个ParentViewController ):

-(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 AppDelegateSWRevealViewControllerDelegate分配给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如下:

-(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更新:添加这一行[revealController.frontViewController.revealViewController tapGestureRecognizer]以在点击 frontviewcontroller 时关闭显示的控制器

Swift version to @hardluckbaby answer: @hardluckbaby 的 Swift 版本回答:

In MenuViewController ( Rear view controller ):MenuViewController后视图控制器)中:

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):FrontViewController 中(如@hardluckbaby 所说,您可以为所有前视图控制器创建一个ParentViewController ):

override func viewDidLoad() {
    super.viewDidLoad()

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

As John Explained: Although these solutions do work, I don't think any of them address the original question, which is actually quite simple:正如约翰解释的那样:虽然这些解决方案确实有效,但我认为它们中的任何一个都没有解决最初的问题,这实际上很简单:

There are 2 steps involved:涉及2个步骤:

  1. Add the following methods to your FrontViewController.m:将以下方法添加到 FrontViewController.m:

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

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

  2. Make your front view controller be a delegate of SWRevealViewController in the FrontViewController.h file:使您的前视图控制器成为 FrontViewController.h 文件中 SWRevealViewController 的委托:

(eg @interface HomeViewController : UIViewController ) where my FrontViewController was named HomeViewController (例如 @interface HomeViewController : UIViewController )我的 FrontViewController 被命名为 HomeViewController

and also in the FrontViewController.m file with the following on ViewDidLoad:并且还在 FrontViewController.m 文件中包含以下关于 ViewDidLoad 的内容:

self.revealViewController.delegate = self; self.revealViewController.delegate = self; Problem solved!问题解决了! Much easier than creating parent classes, etc.比创建父类等容易得多。

This will help you solve the user interactions for the FrontView controller lovely I would just add the following change taken from Xun's response also above and you will solve both the user interactions and the hide menu when user taps FrontViewController.这将帮助您解决 FrontView 控制器的用户交互问题,我只想添加从 Xun 的响应中获取的以下更改,当用户点击 FrontViewController 时,您将解决用户交互和隐藏菜单。

- (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;
      //Hides the menu when user taps FrontViewController
       [revealController.frontViewController.revealViewController tapGestureRecognizer];
    } 
}

Swift 3.0 simple and fast method. Swift 3.0简单快捷的方法。

Frontviewcontoller code here... Frontviewcontoller 代码在这里...

override func viewDidLoad() {
    super.viewDidLoad()
     if self.revealViewController() != nil {
        let rewel:SWRevealViewController  = revealViewController()
        rewel.panGestureRecognizer()
        rewel.tapGestureRecognizer() 
    }
}

SideDrowerviewcontoller code here... SideDrowerviewcontoller 代码在这里...

override func viewWillAppear(_ animated: Bool) {
  let rewel = self.revealViewController()
      rewel?.frontViewController.view.isUserInteractionEnabled = false
    rewel?.frontViewController.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}

override func viewWillDisappear(_ animated: Bool) {
    let rewel = self.revealViewController()
        rewel?.frontViewController.view.isUserInteractionEnabled = true
}

当后视图打开时,将子视图添加到前视图。

In viewWillAppear method of your menu items controller, Just create an overlay button on the front view and set action to revealToggle: of revealViewController在您的菜单项控制器的 viewWillAppear 方法中,只需在前视图上创建一个叠加按钮并将操作设置为revealToggle:ofrevealViewController

-(void)viewWillAppear:(BOOL)animated 
{
    [super viewWillAppear:animated];
    overlayView = [UIButton buttonWithType:UIButtonTypeCustom];
    overlayView.frame = self.revealViewController.frontViewController.view.bounds;
    overlayView.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.8];
    overlayView.tag = 999;
    [overlayView addTarget:self.revealViewController action:@selector(revealToggle:) forControlEvents:UIControlEventTouchUpInside];
    [overlayView addTarget:self.revealViewController action:@selector(revealToggle:) forControlEvents:UIControlEventTouchDragOutside];
    [self.revealViewController.frontViewController.view addSubview:overlayView];
}

In revealTogglle method remove the overlay button if any:在revealToggle方法中删除覆盖按钮(如果有):

- (void)revealToggleAnimated:(BOOL)animated
{
    UIButton *overlayView = (UIButton*)[self.view viewWithTag:999];
    if (overlayView) {
        [overlayView removeFromSuperview];
        overlayView = nil;
    }
    // rest of the code...
}

Although these solutions do work, I don't think any of them address the original question, which is actually quite simple:尽管这些解决方案确实有效,但我认为它们中的任何一个都没有解决最初的问题,这实际上很简单:

There are 2 steps involved:涉及2个步骤:

1) Add the following methods to your FrontViewController.m : 1) 将以下方法添加到您的FrontViewController.m

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

2) Make your front view controller be a delegate of SWRevealViewController in the FrontViewController.h file: 2)让你的前视图控制器成为FrontViewController.h文件中 SWRevealViewController 的委托:

(e.g. @interface HomeViewController : UIViewController <SWRevealViewControllerDelegate>)

where my FrontViewController was named HomeViewController我的 FrontViewController 被命名为 HomeViewController

and also in the FrontViewController.m file with the following on ViewDidLoad:并且还在FrontViewController.m文件中包含以下关于 ViewDidLoad 的内容:

self.revealViewController.delegate = self;

Problem solved!问题解决了! Much easier than creating parent classes, etc.比创建父类等容易得多。

Another way is to have an overlay view when the rear view is revealed.另一种方法是在显示后视图时有一个覆盖视图。 You can use this updated library https://github.com/NSRover/SWRevealViewController and make sure you include shouldUseFrontViewOverlay = true when the rear view is revealed.您可以使用此更新的库https://github.com/NSRover/SWRevealViewController并确保在显示后视图时包含 shouldUseFrontViewOverlay = true 。

class SideMenuViewController: UITableViewController {

  override func viewDidLoad() {
    super.viewDidLoad()
    self.revealViewController().delegate = self
  }

}

extension SideMenuViewController: SWRevealViewControllerDelegate {

  func revealController(revealController: SWRevealViewController!, willMoveToPosition position: FrontViewPosition) {
    if position == .Left {
      revealController.frontViewController.view.userInteractionEnabled = true
    }

    if position == .Right {
      revealController.frontViewController.view.userInteractionEnabled = false
    }
  }

}
On MenuTableViewController/ Rear VC, add SWRevealViewControllerDelegate.

    override func viewDidLoad() {
        super.viewDidLoad()
        self.revealViewController().delegate = self

        if self.revealViewController() != nil {
            self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
        }
    }

Add this delegate method.

func revealController(revealController: SWRevealViewController!, didMoveToPosition position: FrontViewPosition) {
        if(position.rawValue == 4)
        {
            //move to rear
            self.revealViewController().frontViewController.view.userInteractionEnabled =  false
        }
        else if (position.rawValue == 3)
        {
            //move to front - dashboard VC
            self.revealViewController().frontViewController.view.userInteractionEnabled =  true
        }
    }
    func revealController(revealController: SWRevealViewController!, willMoveToPosition position: FrontViewPosition) {

//will perform the same function as the above delegate method.
    }

Consider following solution, works perfect考虑以下解决方案,完美运行

private let DimmingViewTag = 10001

extension UIViewController: SWRevealViewControllerDelegate {    

    func removeInteractionFromFrontViewController() {

        revealViewController().delegate = self

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

    //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()
        }
    }
}

Simple usage in UIViewController : UIViewController简单用法:

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

    removeInteractionFromFrontViewController()
}

Addition to hardluckbaby answer.除了hardluckbaby答案。

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.如果此时您运行您的应用程序,看起来 Tap Gesture 有效(点击 Front View 将关闭菜单),但不是 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:我不确定为什么会这样,但是为了启用滑动手势来关闭菜单,请在 MenuViewController 中添加以下代码:

on viewWillAppear:在 viewWillAppear 上:

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

It adds some undesired behavior, eg pan gesture will close rear view when starts on it.它增加了一些不受欢迎的行为,例如平移手势会在开始时关闭后视。

Default pan gesture may not work if you add it to your own view somewhere, something like on viewDidLoad of your front view controller:如果您将它添加到您自己的视图中的某处,则默认平移手势可能不起作用,例如在您的前视图控制器的viewDidLoad上:

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

Remove such lines and this should works as expected, for pan and tap gestures删除这些行,这应该按预期工作,用于平移和点击手势

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

I was using the viewWillAppear and viewWillDisappear functions but as I have subviews for almost every item in the side menu I had.我正在使用 viewWillAppear 和 viewWillDisappear 函数,但是因为我在侧面菜单中几乎每个项目都有子视图。 My issue was that I had a input field active (keyboard displaying) and accessed the side menu.我的问题是我有一个输入字段处于活动状态(键盘显示)并访问了侧边菜单。 In the root menu the keyboard hid but after I entered a submenu keyboard showed up again.在根菜单中,键盘隐藏,但在我进入子菜单后,键盘再次出现。 To solve this I changed the approach to enable and disable the interaction in revealController like this:为了解决这个问题,我改变了在revealController中启用和禁用交互的方法,如下所示:

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

Firstly just set your delegate : self.revealViewController.delegate = self;首先设置你的委托: self.revealViewController.delegate = self; and the delegate method are given below :和委托方法如下:

- (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position
{
    static NSInteger tagLockView = 123456789;
    if (revealController.frontViewPosition == FrontViewPositionRight)
    {
        UIView *lockView = [self.view viewWithTag:tagLockView];

        [UIView animateWithDuration:0.3 animations:^{
            lockView.alpha = 0;
        } completion:^(BOOL finished) {
            [lockView removeFromSuperview];
        }];
    }
    else if (revealController.frontViewPosition == FrontViewPositionLeft)
    {
        UIView *lockView = [[UIView alloc] initWithFrame:self.view.bounds];
        lockView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        lockView.tag = tagLockView;
        lockView.backgroundColor = [UIColor blackColor];
        lockView.alpha = 0;
        [lockView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self.revealViewController action:@selector(revealToggle:)]];
        [self.view addSubview:lockView];
        [UIView animateWithDuration:0.3 animations:^{
            lockView.alpha = 0.5;
        }];
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Swift 2-SWRevealViewController:菜单打开时删除前视图上的交互 - Swift 2 - SWRevealViewController: Remove interaction on frontview when menu is open SWRevealViewController使侧边栏按钮变为静态,并使RearView出现在frontView的顶部 - SWRevealViewController make sidebar button static & make the rearView appear on top of the frontView 用户在frontView中时,SWRevealViewController停止轻击手势 - SWRevealViewController stop tap gesture when user is in frontView SWRevealViewController在显示左视图时迅速禁用与前视图(地图)的交互3 - SWRevealViewController disable interaction with front view(map) when left view are revealed swift 3 修改SWRevealViewController中frontView的框架 - Modify frame of the frontView in SWRevealViewController 如何将选项卡添加到SWRevealViewController的前视图控制器 - How to add a tabbar to the frontview controller of SWRevealViewController 如何删除SWRevealViewController? - How to remove SWRevealViewController? 如何使用SWRevealViewController禁用边栏菜单中的交互 - How to Disable Interaction in Sidebar Menu using SWRevealViewController SWRevealViewController如何删除滑动手势 - SWRevealViewController how to remove swipe gesture 选择时停止SWRevealViewController动画 - Stop SWRevealViewController animation when select
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM