web-dev-qa-db-ja.com

SWRevealViewController:背面が表示されたときに前面のインタラクションを削除します

背面図が表示されたら、正面図でのユーザー操作を無効にする必要があります。同じことを尋ねている他の人を見つけましたが、私が見たコードをどこに、どのように実装するのか本当に理解できません。

例:このコードは 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メソッドに追加しようとしましたが、成功しませんでした

誰かが私を正しい方向に向けることができるかどうかを感謝します。

14
user3306356

最近、共有したいソリューションを思いつきました(2か月遅れてすみません)。

メニューが開いているときにフロントビューでのユーザー操作を無効にするために、MenuViewControllerに次のコードを追加しました。

onviewWillAppear

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

およびviewWillDisappear

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

これにより、Front View Controllerでのすべてのユーザー操作が無効になります。つまり、メニューを閉じるためのスライド/タップジェスチャも無効になります。

これで、ParentViewControllerを作成し、すべてのビューコントローラー(メニュー項目)をそのサブクラスにしました。

私のviewDidLoadに、次のコードを配置します。

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

この時点でアプリを実行すると、タップジェスチャは機能しているように見えますが(正面図をタップするとメニューが閉じます)、パンジェスチャは機能しません。これがなぜそうなのかはわかりませんが、スライドジェスチャでメニューを閉じることができるようにするには、次のコードをMenuViewControllerに追加します。

onviewWillAppear

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

お役に立てれば!

53
aj_f

私は別のアプローチを使用して同じ結果を達成しましたが、それが役立つかどうかはわかりません。

SWRevealViewControllerDelegateAppDelegateに割り当てます

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

[〜#〜] updated [〜#〜]:この行を追加_[revealController.frontViewController.revealViewController tapGestureRecognizer]_して、frontviewcontrollerをタップしたときに表示されたコントローラーを閉じます

13
xun

@hardluckbabyの回答への迅速なバージョン:

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

Johnが説明したHeyGuys:これらのソリューションは機能しますが、実際には非常に単純な元の質問に対処しているソリューションはないと思います。

関係する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];
    } 
}
3
Pablo Segura

Swift 3.シンプルで高速な方法。

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
}
2
Rex

これらのソリューションは機能しますが、実際には非常に単純な元の質問に対処しているソリューションはないと思います。

関係する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;

問題が解決しました!親クラスなどを作成するよりもはるかに簡単です。

1
John

背面図が開いているときに、正面図にサブビューを追加します。

1
Mayank Jain

もう1つの方法は、背面図が表示されたときにオーバーレイビューを表示することです。この更新されたライブラリを使用できます https://github.com/NSRover/SWRevealViewController そして、背面図が表示されたら、shouldUseFrontViewOverlay = trueを含めるようにしてください。

1
thedansaps

メニュー項目コントローラーのviewWillAppearメソッドで、正面図にオーバーレイボタンを作成し、revealViewControllerのrevealToggle:にアクションを設定するだけです。

-(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...
}
1
Amita_S
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
    }
  }

}
1
Bryan Lin

私は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];
    }
}
0
mxmlc

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];
0
art-of-dreams

まず、デリゲートを設定します。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;
        }];
    }

}
0
Priti Kanauziya

次の解決策を検討してください、完璧に機能します

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()
}
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.
    }
0
A.G