代码之家  ›  专栏  ›  技术社区  ›  Mou某

SWRevealViewController:显示后视镜时删除前视图上的交互

  •  14
  • Mou某  · 技术社区  · 11 年前

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

    我从 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 没有成功的方法

    如果有人能给我指明正确的方向,请表示感谢。

    15 回复  |  直到 8 年前
        1
  •  53
  •   aj_f    11 年前

    我最近提出了一个解决方案,我想与大家分享 (如果晚了两个月,很抱歉)。

    为了在菜单打开时禁用前视图上的用户交互,我在 菜单视图控制器 :

    在…上 视图将出现 :

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

    视图将消失 :

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

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

    现在,我已经创建了一个 父视图控制器 并使所有视图控制器(菜单项)成为其子类。

    在我的 视图DidLoad ,我输入了以下代码:

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

    如果此时运行应用程序,则“轻触手势”似乎有效(点击“前视图”将关闭“菜单”),但“平移手势”无效。我不知道为什么会这样,但为了使滑动手势关闭菜单,请在 菜单视图控制器 :

    在…上 视图将出现 :

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

    总而言之,以下是您需要的:

    在您的 菜单视图控制器 :

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

    在菜单项的视图控制器上(您可以 父视图控制器 对于所有这些):

    -(void)viewDidLoad {
        [super viewDidLoad];
    
        SWRevealViewController *revealController = [self revealViewController];
        [revealController panGestureRecognizer];
        [revealController tapGestureRecognizer];
    }
    

    希望这有帮助!

        2
  •  13
  •   xun    10 年前

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

    分配 SWRevealViewControllerDelegate 应用程序委托

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

    然后在 代表 方法 -(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
  •  6
  •   Ashok    9 年前

    @hardluckbaby的Swift版本回答:

    在里面 菜单视图控制器 ( 后视控制器 ):

    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
    }
    

    在里面 FrontView控制器 (你可以 父视图控制器 对于@hardluckbaby所说的所有前视图控制器):

    override func viewDidLoad() {
        super.viewDidLoad()
    
        if let revealController = self.revealViewController() {
            revealController.panGestureRecognizer()
            revealController.tapGestureRecognizer()
        }
    }
    
        4
  •  3
  •   peterh Eli    4 年前

    正如John所解释的:虽然这些解决方案确实有效,但我认为它们都没有解决最初的问题,这实际上很简单:

    涉及两个步骤:

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

      • (void)revalController:(SWRevealViewController*)revalController willMoveToPosition:(FrontViewPosition)位置{ if(位置==FrontViewPositionLeft){ self.view.userInteractionEnabled=是; }其他{ self.view.userInteractionEnabled=否; } }

      • (void)revalController:(SWRevealViewController*)revalController didMoveToPosition:(FrontViewPosition)位置{ if(位置==FrontViewPositionLeft){ self.view.userInteractionEnabled=是; }其他{ self.view.userInteractionEnabled=否; } }

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

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

    以及FrontViewController.m文件中的ViewDidLoad上的以下内容:

    self.revelViewController.default=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
  •  2
  •   Raksha Saini    7 年前

    斯威夫特3.0 方法简单快速。

    此处为Frontviewcontroller代码。。。

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

    SideDrowerview控制器代码。。。

    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
  •  1
  •   Mayank Jain Pushpendra Rathor    11 年前

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

        7
  •  1
  •   Amita_S    10 年前

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

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

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

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

    尽管这些解决方案确实有效,但我认为它们都没有解决最初的问题,这实际上很简单:

    涉及两个步骤:

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

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

    其中我的FrontViewController被命名为HomeViewController

    以及 FrontViewController.m ViewDidLoad上包含以下内容的文件:

    self.revealViewController.delegate = self;
    

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

        9
  •  1
  •   thedansaps    9 年前

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

        10
  •  1
  •   Bryan Lin    9 年前
    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
  •  0
  •   Alvin George    9 年前
    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
  •  0
  •   Bartłomiej Semańczyk    8 年前

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

    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
  •  0
  •   art-of-dreams    8 年前

    添加到 硬鹿宝宝 答复

    如果此时运行应用程序,则点击 手势有效(点击前视图将关闭菜单),但不 潘手势。我不知道为什么会这样,但为了 使用滑动手势关闭菜单,在菜单中添加以下代码 菜单视图控制器:

    在视图中将出现:

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

    它增加了一些不期望的行为,例如,当启动时,平移手势将关闭后视图。

    如果您将默认平移手势添加到您自己的视图中,例如在 视图DidLoad 前视图控制器:

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

    删除这些线条,这应该可以像预期的那样,用于平移和轻敲手势

    SWRevealViewController *revealController = [self revealViewController];
    [revealController panGestureRecognizer];
    [revealController tapGestureRecognizer];
    
        14
  •  0
  •   mxmlc    8 年前

    我使用的是viewWillAppear和viewWillDisappear功能,但因为我在侧菜单中几乎每个项目都有子视图。我的问题是我有一个激活的输入字段(键盘显示)并访问了侧菜单。在根菜单中,键盘隐藏,但在我进入子菜单后,键盘再次出现。为了解决这个问题,我改变了在revalController中启用和禁用交互的方法,如下所示:

    - (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
  •  0
  •   Priti Kanauziya    7 年前

    首先,只需设置您的代理人: self.revelViewController.default=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;
            }];
        }
    
    }