14

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

例如:我从链接中找到了这段代码,

- (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方法中,但没有成功

感谢有人能指出我正确的方向。

4

15 回答 15

53

我最近想出了一个我想分享的解决方案(对不起,如果晚了 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];
}

希望这可以帮助!

于 2014-05-26T04:04:24.970 回答
13

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

SWRevealViewControllerDelegate分配给AppDelegate

- (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 时关闭显示的控制器

于 2014-06-23T03:19:04.180 回答
6

@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()
    }
}
于 2016-03-22T11:45:53.233 回答
3

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

涉及两个步骤:

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

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

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

  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];
    } 
}
于 2016-04-27T01:49:28.677 回答
2

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
}
于 2017-07-27T10:30:36.413 回答
1

In viewWillAppear method of your menu items controller, Just create an overlay button on the front view and set action to revealToggle: of 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];
}

In revealTogglle method remove the overlay button if any:

- (void)revealToggleAnimated:(BOOL)animated
{
    UIButton *overlayView = (UIButton*)[self.view viewWithTag:999];
    if (overlayView) {
        [overlayView removeFromSuperview];
        overlayView = nil;
    }
    // rest of the code...
}
于 2015-01-02T20:32:53.327 回答
1

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

于 2014-03-24T05:13:33.490 回答
1

尽管这些解决方案确实有效,但我认为它们中的任何一个都不能解决最初的问题,这实际上非常简单:

涉及两个步骤:

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

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

self.revealViewController.delegate = self;

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

于 2015-04-13T02:10:34.580 回答
1

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

于 2015-07-15T06:00:54.770 回答
1
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
    }
  }

}
于 2016-02-18T16:31:41.253 回答
0

首先只需设置您的委托: 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;
        }];
    }

}
于 2017-06-21T10:12:00.013 回答
0

考虑以下解决方案,完美运行

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()
}
于 2016-07-01T07:45:03.820 回答
0

除了hardluckbaby答案。

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

在 viewWillAppear 上:

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

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

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

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

删除这些行,这应该可以按预期工作,用于平移和点击手势

SWRevealViewController *revealController = [self revealViewController];
[revealController panGestureRecognizer];
[revealController tapGestureRecognizer];
于 2016-08-27T12:32:14.563 回答
0

我正在使用 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];
    }
}
于 2016-10-21T12:17:00.410 回答
0
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.
    }
于 2016-01-18T13:51:46.660 回答