【问题标题】:SWRevealViewController: Remove interaction on frontview when rearview is revealedSWRevealViewController:在显示后视图时删除前视图上的交互
【发布时间】:2014-05-01 08:09:53
【问题描述】:

当显示后视图时,我需要禁用前视图上的用户交互。发现其他一些人问同样的问题,但不能真正理解在哪里或如何实现我所看到的代码。

例如:我从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;
    } 
}

还发现了一些其他链接

我有此代码,但不确定插入此代码的正确位置。我尝试将它添加到我的前/后视图以及 SWRevealViewController 方法中,但没有成功

如果有人能指出我正确的方向,不胜感激。

【问题讨论】:

  • 我同意下面 Mayank 的回答。这将是一种更简单的方法。
  • @MayankJain 你能给我一点代码吗?!
  • 考虑关注answer

标签: ios uiviewcontroller user-interaction swrevealviewcontroller


【解决方案1】:

我最近想出了一个我想分享的解决方案 (对不起,如果晚了 2 个月)。

为了在菜单打开时禁用前视图上的用户交互,我在 MenuViewController 上添加了以下代码:

关于viewWillAppear

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

viewWillDisappear上:

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

这将禁用前视图控制器上的所有用户交互,这意味着关闭菜单的滑动/点击手势也将被禁用。

现在,我创建了一个 ParentViewController 并将所有视图控制器(菜单项)作为它的子类。

在我的 viewDidLoad 上,我输入了以下代码:

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

如果您此时运行您的应用程序,点击手势似乎有效(点击前视图将关闭菜单),但不是平移手势。我不确定为什么会这样,但为了让滑动手势关闭您的菜单,请在 MenuViewController 中添加以下代码:

viewWillAppear上:

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

总而言之,这就是您需要的:

在您的 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];
}

在您的菜单项的视图控制器上(您可以为所有菜单项创建一个 ParentViewController):

-(void)viewDidLoad {
    [super viewDidLoad];

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

希望这会有所帮助!

【讨论】:

  • 它不仅仅是帮助 - 超级简单和超级超级
  • 你也可以使用这个分叉:nsrover.wordpress.com/2014/08/06/…
  • 唯一的障碍是屏幕上任何地方的平移手势,包括在后菜单屏幕上都会移动 frontViewController。有人有办法限制可滑动区域吗?
  • 非常聪明.. 谢谢
  • 对于 viewDiDLoad 部分的最后一部分,你将如何用 swift 编写它? SWRevealViewController *revealController = [self revealViewController]; [revealController panGestureRecognizer]; [revealController tapGestureRecognizer]; 我能够让第一部分在 Swift 中工作以禁用手势,只需要让它们恢复 :)
【解决方案2】:

我使用了另一种方法来实现相同的结果,不确定是否有帮助。

SWRevealViewControllerDelegate 分配给 AppDelegate

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

    // other bootstrapping code
}

然后在 delegate 方法中-(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];
    }
}

更新:添加此行[revealController.frontViewController.revealViewController tapGestureRecognizer] 以在点击 frontviewcontroller 时关闭显示的控制器

【讨论】:

    【解决方案3】:

    @hardluckbaby 的 Swift 版本回答:

    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
    }
    

    FrontViewController 中(您可以像@hardluckbaby 所说的那样为所有前视图控制器制作一个ParentViewController):

    override func viewDidLoad() {
        super.viewDidLoad()
    
        if let revealController = self.revealViewController() {
            revealController.panGestureRecognizer()
            revealController.tapGestureRecognizer()
        }
    }
    

    【讨论】:

      【解决方案4】:

      正如约翰所解释的:虽然这些解决方案确实有效,但我认为它们中的任何一个都不能解决最初的问题,这实际上很简单:

      涉及两个步骤:

      1. 将以下方法添加到您的 FrontViewController.m:

        • (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position { 如果(位置 == FrontViewPositionLeft){ self.view.userInteractionEnabled = YES; } 别的 { self.view.userInteractionEnabled = 否; } }

        • (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)位置{ 如果(位置 == FrontViewPositionLeft){ self.view.userInteractionEnabled = YES; } 别的 { self.view.userInteractionEnabled = 否; } }

      2. 使您的前视图控制器成为 FrontViewController.h 文件中 SWRevealViewController 的代表:

      (例如 @interface HomeViewController : UIViewController ) 我的 FrontViewController 被命名为 HomeViewController

      以及在 ViewDidLoad 上的 FrontViewController.m 文件中:

      self.revealViewController.delegate = self; 问题解决了!比创建父类等容易得多。

      这将帮助您解决可爱的 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];
          } 
      }
      

      【讨论】:

        【解决方案5】:

        Swift 3.0简单快速的方法。

        此处为 Frontviewcontoller 代码...

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

        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
        }
        

        【讨论】:

          【解决方案6】:

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

          【讨论】:

          • 我可以得到一些示例代码吗?我尝试在我的 ViewDidLoad 中添加for(UIView *view in self.revealViewController){....},但我认为我做错了什么
          【解决方案7】:

          在您的菜单项控制器的 viewWillAppear 方法中,只需在前视图上创建一个覆盖按钮并将操作设置为revealToggle:revealViewController

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

          在revealTogglle方法中删除覆盖按钮(如果有):

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

          【讨论】:

            【解决方案8】:

            虽然这些解决方案确实有效,但我认为它们中的任何一个都不能解决原来的问题,这实际上很简单:

            涉及两个步骤:

            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) 在 FrontViewController.h 文件中让您的前视图控制器成为 SWRevealViewController 的代表:

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

            我的 FrontViewController 被命名为 HomeViewController

            FrontViewController.m 文件中,ViewDidLoad 上有以下内容:

            self.revealViewController.delegate = self;
            

            问题解决了!比创建父类等容易得多。

            【讨论】:

            • 谢谢!非常干净简单
            • 但滑动菜单仅在单击菜单按钮时隐藏& panGestureRecognizer() & tapGestureRecognizer() 不起作用。
            • shouldUseFrontViewOverlay 必须设置为 true。
            【解决方案9】:

            另一种方法是在显示后视图时进行叠加视图。您可以使用这个更新的库https://github.com/NSRover/SWRevealViewController 并确保在显示后视图时包含 shouldUseFrontViewOverlay = true。

            【讨论】:

              【解决方案10】:
              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
                  }
                }
              
              }
              

              【讨论】:

                【解决方案11】:
                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.
                    }
                

                【讨论】:

                  【解决方案12】:

                  考虑以下解决方案,效果完美

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

                  UIViewController中的简单用法:

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

                  【讨论】:

                    【解决方案13】:

                    hardluckbaby 答案的补充。

                    如果您此时运行您的应用程序,那么点击 手势有效(点击前视图将关闭菜单),但不是 平移手势。我不确定为什么会这样,但是为了启用 关闭菜单的滑动手势,在您的菜单中添加以下代码 菜单视图控制器:

                    在 viewWillAppear 上:

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

                    它增加了一些不受欢迎的行为,例如平移手势将在启动时关闭后视图。

                    如果您将默认平移手势添加到您自己的某个视图中,例如在前视图控制器的 viewDidLoad 上,默认平移手势可能不起作用:

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

                    删除这样的线条,这应该可以按预期工作,用于平移和点击手势

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

                    【讨论】:

                      【解决方案14】:

                      我使用的是 viewWillAppear 和 viewWillDisappear 函数,但我的侧边菜单中几乎每个项目都有子视图。我的问题是我有一个输入字段处于活动状态(键盘显示)并访问了侧面菜单。在根菜单中,键盘隐藏了,但在我进入子菜单后,键盘又出现了。为了解决这个问题,我改变了在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];
                          }
                      }
                      

                      【讨论】:

                        【解决方案15】:

                        首先只需设置您的委托: self.revealViewController.delegate = self; 委托方法如下:

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

                        【讨论】:

                          猜你喜欢
                          • 2016-06-02
                          • 2017-05-17
                          • 2016-10-03
                          • 2015-07-03
                          • 2014-04-12
                          • 2017-01-14
                          • 2017-12-31
                          • 2017-04-03
                          • 2017-01-19
                          相关资源
                          最近更新 更多