簡體   English   中英

SWRevealViewController:顯示后視時移除前視上的交互

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

當顯示后視圖時,我需要禁用前視圖上的用戶交互。 發現其他一些人提出了同樣的問題,但無法真正理解在哪里或如何實現我所看到的代碼。

例如:我從鏈接中找到了這個代碼,

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

感謝有人能指出我正確的方向。

我最近想出了一個我想分享的解決方案(抱歉,如果晚了 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];

如果此時您運行您的應用程序,看起來 Tap Gesture 有效(點擊 Front View 將關閉菜單),但不是 Pan Gesture。 我不確定為什么會這樣,但是為了啟用滑動手勢來關閉菜單,請在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];
}

希望這可以幫助!

我使用了另一種方法來實現相同的結果,不確定它是否有幫助。

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 時關閉顯示的控制器

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

正如約翰解釋的那樣:雖然這些解決方案確實有效,但我認為它們中的任何一個都沒有解決最初的問題,這實際上很簡單:

涉及2個步驟:

  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 的委托:

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

並且還在 FrontViewController.m 文件中包含以下關於 ViewDidLoad 的內容:

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

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
}

當后視圖打開時,將子視圖添加到前視圖。

在您的菜單項控制器的 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];
}

在revealToggle方法中刪除覆蓋按鈕(如果有):

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

盡管這些解決方案確實有效,但我認為它們中的任何一個都沒有解決最初的問題,這實際上很簡單:

涉及2個步驟:

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;

問題解決了! 比創建父類等容易得多。

另一種方法是在顯示后視圖時有一個覆蓋視圖。 您可以使用此更新的庫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.
    }

考慮以下解決方案,完美運行

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

除了hardluckbaby答案。

如果此時您運行您的應用程序,看起來 Tap Gesture 有效(點擊 Front View 將關閉菜單),但不是 Pan Gesture。 我不確定為什么會這樣,但是為了啟用滑動手勢來關閉菜單,請在 MenuViewController 中添加以下代碼:

在 viewWillAppear 上:

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

它增加了一些不受歡迎的行為,例如平移手勢會在開始時關閉后視。

如果您將它添加到您自己的視圖中的某處,則默認平移手勢可能不起作用,例如在您的前視圖控制器的viewDidLoad上:

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

刪除這些行,這應該按預期工作,用於平移和點擊手勢

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

我正在使用 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];
    }
}

首先設置你的委托: 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;
        }];
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM