web-dev-qa-db-de.com

Deaktivieren der Zurück-Wisch-Geste in UINavigationController unter iOS 7

In iOS 7 Apple hat ein neues Standardnavigationsverhalten hinzugefügt. Sie können vom linken Rand des Bildschirms wischen, um zum Navigationsstapel zurückzukehren. In meiner App steht dieses Verhalten jedoch im Widerspruch zu meinem benutzerdefinierten Link Ist es also möglich, diese neue Geste in UINavigationController zu deaktivieren?

318
ArtFeel

Ich habe eine Lösung gefunden:

Ziel-C:

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

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

570
ArtFeel

Ich habe herausgefunden, dass es nicht immer funktioniert, die Geste auf "Nur deaktiviert" zu setzen. Es funktioniert, aber für mich erst, nachdem ich das Backgesture einmal benutzt habe. Das zweite Mal würde es nicht das Backgesture auslösen.

Für mich bestand das Problem darin, die Geste zu delegieren und die Methode shouldbegin zu implementieren, um NO zurückzugeben:

- (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;
}
46
Antoine

Entfernen Sie einfach die Gestenerkennung von NavigationController. In iOS 8 arbeiten.

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

Ab iOS 8 funktioniert die akzeptierte Antwort nicht mehr. Ich musste das Swipping stoppen, um die Geste auf meinem Hauptspielbildschirm zu schließen.

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

Ich habe Twans Antwort ein wenig verfeinert, weil:

  1. ihr Ansichtscontroller ist möglicherweise als Stellvertreter für andere Gestenerkenner festgelegt
  2. wenn Sie den Delegaten auf nil setzen, kommt es zu Problemen, wenn Sie zum Stammansichts-Controller zurückkehren und eine Wischgeste ausführen, bevor Sie an eine andere Stelle navigieren.

Im folgenden Beispiel wird iOS 7 vorausgesetzt:

{
    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;
}
20
Ja͢ck

Bitte setzen Sie dies in 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

Für Swift:

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

es funktioniert für mich in iOS 10 und höher:

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

}

es funktioniert nicht mit der viewDidLoad () -Methode.

5
Logic

BEARBEITEN

Wenn Sie die Swipe-Back-Funktion für bestimmte Navigations-Controller verwalten möchten, sollten Sie SwipeBack verwenden.

Hiermit können Sie navigationController.swipeBackEnabled = NO.

Zum Beispiel:

#import <SwipeBack/SwipeBack.h>

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

Es kann über CocoaPods installiert werden.

pod 'SwipeBack', '~> 1.0'

Ich entschuldige mich für die mangelnde Erklärung.

5
devxoul

Alle diese Lösungen manipulieren die Gestenerkennung von Apple auf eine Weise, die sie nicht empfehlen. Mir wurde gerade von einem Freund gesagt, dass es eine bessere Lösung gibt:

[navigationController.interactivePopGestureRecognizer requireGestureRecognizerToFail: myPanGestureRecognizer];

wobei myPanGestureRecognizer der Gestenerkenner ist, den Sie für z. zeige dein Menü. Auf diese Weise wird die Gestenerkennung von Apple beim Drücken eines neuen Navigationscontrollers nicht wieder aktiviert, und Sie müssen sich nicht auf Verzögerungen verlassen, die zu früh ausgelöst werden können, wenn Ihr Telefon in den Energiesparmodus versetzt oder stark ausgelastet wird.

Wenn ich das hier lasse, weil ich weiß, dass ich mich beim nächsten Mal nicht daran erinnern kann, dann habe ich hier die Lösung für das Problem.

3
uliwitness

Meine Methode. Ein Gestenerkenner, der alle anordnet:

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

Wichtig: Setzen Sie den Delegaten an keiner Stelle im Navigationsstapel zurück: navigationController!.interactivePopGestureRecognizer!.delegate = nil

3
SoftDesigner

Dies ist der Weg auf Swift 3

funktioniert bei mir

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

Dies funktioniert in viewDidLoad: Für iOS 8:

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

Viele der Probleme konnten mit Hilfe des guten alten dispatch_after Gelöst werden.

Beachten Sie, dass diese Lösung möglicherweise unsicher ist. Verwenden Sie jedoch Ihre eigenen Argumente.

pdate

Für iOS 8.1 sollte die Verzögerungszeit 0,5 Sekunden betragen

Unter iOS 9.3 ist keine Verzögerung mehr erforderlich. Sie können dies einfach in Ihrem viewDidLoad platzieren:
(TBD wenn unter iOS 9.0-9.3)

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

Keine der angegebenen Antworten hat mir geholfen, das Problem zu lösen. Meine Antwort hier posten; kann für jemanden hilfreich sein

Deklarieren Sie private var popGesture: UIGestureRecognizer? Als globale Variable in Ihrem Viewcontroller. Implementieren Sie dann den Code in den Methoden viewDidAppear und viewWillDisappear

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

Dies deaktiviert das Zurückwischen in iOS v8.x und höher

2
Augustine P A

Für Swift 4 funktioniert dies:

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

Bei den meisten Viewcontrollern hat es bei mir geklappt.

self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false

Bei einigen Viewcontrollern wie UIPageViewController hat es nicht funktioniert. Auf UIPageViewController's pagecontentviewcontroller funktionierte folgender Code für mich.

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
}

Auf UIGestureRecognizerDelegate,

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