web-dev-qa-db-ja.com

iOS 7のUINavigationControllerでバックスワップチェッカーを無効にする方法

IOS 7では、Appleは新しいデフォルトのナビゲーション動作を追加しました。ナビゲーションスタックに戻るには、画面の左端からスワイプすることができます。しかし私のアプリでは、この動作は私のカスタム左メニューと衝突します。それで、UINavigationControllerでこの新しいジェスチャーを無効にすることは可能ですか?

316
ArtFeel

私は解決策を見つけました:

Objective-C:

if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
    self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}

Swift 3:
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false

568
ArtFeel

ジェスチャーを無効に設定するだけではうまくいかないことがわかりました。それは動作しますが、私にとってはそれは私がかつて裏表紙を使用した後にのみ行われました。二度目はそれが裏切りを誘発しないでしょう。

私の解決策は、ジェスチャーを委任し、NOを返すようshouldbeginメソッドを実装することでした。

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    // Disable iOS 7 back gesture
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.enabled = NO;
        self.navigationController.interactivePopGestureRecognizer.delegate = self;
    }
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    // Enable iOS 7 back gesture
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.enabled = YES;
        self.navigationController.interactivePopGestureRecognizer.delegate = nil;
    }
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    return NO;
}
45
Antoine

NavigationControllerからジェスチャレコグナイザを削除するだけです。 iOS 8で動作します。

if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)])
    [self.navigationController.view removeGestureRecognizer:self.navigationController.interactivePopGestureRecognizer];
26

IOS 8以降、承認された回答は機能しません。私はメインのゲーム画面でジェスチャーを消すためにスワイプを止める必要がありました。

- (void)viewDidAppear:(BOOL)animated
{
     [super viewDidAppear:animated];

if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
    self.navigationController.interactivePopGestureRecognizer.delegate = self;
    }
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
    self.navigationController.interactivePopGestureRecognizer.delegate = nil;
    }

}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
     return NO;
}
21

Twanの答えを少し洗練しました。

  1. view Controllerが他のジェスチャ認識機能への代理として設定されている可能性があります。
  2. デリゲートをnilに設定すると、ルートビューコントローラに戻って他の場所に移動する前にスワイプジェスチャをするときに問題が発生します。

次の例ではiOS 7を想定しています。

{
    id savedGestureRecognizerDelegate;
}

- (void)viewWillAppear:(BOOL)animated
{
    savedGestureRecognizerDelegate = self.navigationController.interactivePopGestureRecognizer.delegate;
    self.navigationController.interactivePopGestureRecognizer.delegate = self;
}

- (void)viewWillDisappear:(BOOL)animated
{
    self.navigationController.interactivePopGestureRecognizer.delegate = savedGestureRecognizerDelegate;
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    if (gestureRecognizer == self.navigationController.interactivePopGestureRecognizer) {
        return NO;
    }
    // add whatever logic you would otherwise have
    return YES;
}
18
Ja͢ck

これをroot vcに設定してください。

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:YES];
    self.navigationController.interactivePopGestureRecognizer.enabled = NO;

}

-(void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:YES];
    self.navigationController.interactivePopGestureRecognizer.enabled = YES;
}
10
reza_khalafi

Swiftの場合:

navigationController!.interactivePopGestureRecognizer!.enabled = false
8
iPhone 7

編集

特定のナビゲーションコントローラのスワイプバック機能を管理したい場合は、 SwipeBack の使用を検討してください。

これでnavigationController.swipeBackEnabled = NOを設定できます。

例えば:

#import <SwipeBack/SwipeBack.h>

- (void)viewWillAppear:(BOOL)animated
{
    navigationController.swipeBackEnabled = NO;
}

それは CocoaPods を通してインストールすることができます。

pod 'SwipeBack', '~> 1.0'

説明不足のため申し訳ありません。

6
devxoul

それはIOS 10以降で私のために働く:

- (void)viewWillAppear:(BOOL)animated {
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.enabled = NO;
    }

}

viewDidLoad()メソッドでは動作しません。

5
Logic

私の方法それらすべてを統制するためのジェスチャー認識機能

class DisabledGestureViewController: UIViewController: UIGestureRecognizerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        navigationController!.interactivePopGestureRecognizer!.delegate = self
    }

    func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
        // Prevent going back to the previous view
        return !(navigationController!.topViewController is DisabledGestureViewController)
    }
}

重要:ナビゲーションスタックのどこにもデリゲートをリセットしないでください。navigationController!.interactivePopGestureRecognizer!.delegate = nil

3
SoftDesigner

これはSwift 3のやり方です

私のために働く

    self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
3
Tayo119

これらのソリューションはすべて、推奨しない方法でAppleのジェスチャ認識機能を操作します。私は友人からもっと良い解決策があると言われました:

[navigationController.interactivePopGestureRecognizer requireGestureRecognizerToFail: myPanGestureRecognizer];

myPanGestureRecognizerは、あなたが使用しているジェスチャレコグナイザです。あなたのメニューを見せてください。そうすれば、新しいナビゲーションコントローラをプッシュしてもAppleのジェスチャレコグナイザはそれらの機能を有効にすることができず、電話機がスリープ状態になったり重い負荷がかかった場合に早すぎる発火を招くことがあります。

次回必要になったときにこれを覚えていないことがわかっているので、ここに残しておきます。その後、ここで問題の解決策を見つけます。

2
uliwitness

これはiOS 8のviewDidLoad:で動作します。

  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
      self.navigationController.interactivePopGestureRecognizer.enabled = false;
  });

多くの問題は古き良きdispatch_afterの助けを借りて解決することができます。

この解決策は潜在的に危険であることに注意してください、あなた自身の推論を使ってください。

更新

IOS 8.1の場合、遅延時間は0.5秒です。

IOS 9.3では、これ以上遅延は必要ありません。これをviewDidLoadに配置するだけで機能します。
(iOS 9.0-9.3で動作する場合は未定)

navigationController?.interactivePopGestureRecognizer?.enabled = false
2
Dannie P

与えられた答えのどれも私が問題を解決するのを助けませんでした。私の答えをここに投稿してください。誰かに役立つかもしれません

あなたのviewcontrollerでグローバル変数としてprivate var popGesture: UIGestureRecognizer?を宣言してください。それからviewDidAppearviewWillDisappearメソッドでコードを実装

override func viewDidAppear(animated: Bool) {

    super.viewDidAppear(animated)

    if self.navigationController!.respondsToSelector(Selector("interactivePopGestureRecognizer")) {

        self.popGesture = navigationController!.interactivePopGestureRecognizer
        self.navigationController!.view.removeGestureRecognizer(navigationController!.interactivePopGestureRecognizer!)
    }
}


override func viewWillDisappear(animated: Bool) {

    super.viewWillDisappear(animated)

    if self.popGesture != nil {
        navigationController!.view.addGestureRecognizer(self.popGesture!)
    }
}

これにより、iOSv8.x以降ではスワイプバックが無効になります

2
Augustine P A

Swift 4の場合、これは機能します。

class MyViewController: UIViewController, UIGestureRecognizerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        self.navigationController?.interactivePopGestureRecognizer?.gesture.delegate = self
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)

        self.navigationController?.interactivePopGestureRecognizer?.gesture.isEnabled = false
    }

}
1
Mat0

それは私にとってほとんどのビューコントローラでうまくいきました。

self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false

UIPageViewControllerのようないくつかのビューコントローラでは動作しませんでした。以下のUIPageViewControllerのpagecontentviewcontrollerコードは私のために働きました。

override func viewDidLoad() {
   self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
   self.navigationController?.interactivePopGestureRecognizer?.delegate = self
}
override func viewWillDisappear(_ animated: Bool) {
   self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
   self.navigationController?.interactivePopGestureRecognizer?.delegate = nil
}

UIGestureRecognizerDelegateでは、

func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
   if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer {
      return false
}
      return true
}
0
Faris Muhammed