web-dev-qa-db-fra.com

Désactiver le geste de balayage arrière Swift

Cela fait un moment que je regarde autour de moi, mais je n'arrive pas à trouver une solution qui fonctionne.

J'essaie de désactiver le balayage pour revenir au geste d'affichage précédent, dans Swift.

J'ai essayé diverses solutions, notamment:

self.navigationController?.interactivePopGestureRecognizer.enabled = false

et

self.navigationController.interactivePopGestureRecognizer.delegate = self

func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer!) -> Bool {
    return false
}

Existe-t-il une nouvelle méthode pour ce faire ou une autre méthode qui fonctionne?

59
Phil Hudson

Vous pouvez le désactiver, mais cela ne serait pas recommandé car la plupart des utilisateurs iOS reviennent en glissant et en glissant le doigt moins en appuyant sur le bouton Précédent. Si vous voulez le désactiver, il serait plus raisonnable d'utiliser un modal segue _ au lieu d’une séquence Push qui n’est pas si grosse qu’un transfert. Si vous voulez vraiment vous débarrasser de la fonction glisser pour revenir en arrière, je voudrais simplement désactiver le bouton Retour et avoir un bouton Terminé en haut à droite de l'écran.

self.navigationController?.navigationItem.backBarButtonItem?.isEnabled = false;
12
Stefan DeClerck

Ce qui suit est une approche simple pour désactiver et réactiver le balayage.

Swift 3.x & up

Dans une méthode viewDidLoad/willAppear/didAppear, ajoutez:

navigationController?.interactivePopGestureRecognizer?.isEnabled = false

Gardez simplement à l'esprit que si vous le faites avec viewDidLoad, la prochaine fois que vous ouvrirez la vue, celle-ci ne sera peut-être pas définie, selon qu'elle reste ou non dans votre pile.

À moins que vous ne souhaitiez qu'il reste désactivé, vous devrez le réactiver lorsque la vue sera fermée via willMove(toParentViewController:) ou willDisappear. Votre navigationController sera nul à viewDidDisappear, il est donc trop tard.

navigationController?.interactivePopGestureRecognizer?.isEnabled = true

Une note spéciale sur SplitViewControllers:

Comme l'a souligné CompC dans les commentaires, vous devrez appeler le deuxième contrôleur de navigation pour l'appliquer à une vue détaillée en tant que telle:

navigationController?.navigationController?.interactivePopGe‌​stureRecognizer?.isE‌​nabled = false

Swift 2.2 & Objective-C

Swift versions 2.x et ci-dessous:

navigationController?.interactivePopGestureRecognizer?.enabled

Objectif c:

self.navigationController.interactivePopGestureRecognizer.enabled
122
CodeBender

J'ai pu le faire en retournant false dans gestureRecognizerShouldBegin

class ViewController2: UIViewController, UIGestureRecognizerDelegate {
...
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    self.navigationController?.interactivePopGestureRecognizer.delegate = self
}

func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
    return false
}
18
Hari Kunwar

Rien de mal à l'une ou l'autre réponse de Hari ou de Stefan mais ceci est plus succinct. Il suffit de le mettre dans viewDidLoad et vous avez terminé.

if navigationController!.respondsToSelector(Selector("interactivePopGestureRecognizer")) {
    navigationController!.view.removeGestureRecognizer(navigationController!.interactivePopGestureRecognizer)
}

EDIT:

Un petit inconvénient est que si le contrôleur de navigation a été ouvert par une autre vue et qu'il est fermé, vous obtiendrez une erreur EXC_BAD_ACCESS. Pour résoudre ce problème, vous devez enregistrer le UIGestureRecognizer d'origine et le remettre en place lorsque vous quittez la vue.

Déclarer:

private var popGesture: UIGestureRecognizer?

Immédiatement avant de retirer le geste:

popGesture = navigationController!.interactivePopGestureRecognizer

Puis lors de la fermeture de la vue:

If popGesture != nil {
    navigationController!.view.addGestureRecognizer(popGesture!)
}
5
RowanPD

pour objectif -c

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

  self.navigationController.interactivePopGestureRecognizer.enabled = NO;

}
3
Maulik Patel

La logique de RowanPD pour Swift 4

private var popGesture: UIGestureRecognizer?

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    if navigationController!.responds(to: #selector(getter: UINavigationController.interactivePopGestureRecognizer)) {
        self.popGesture = navigationController!.interactivePopGestureRecognizer
        self.navigationController!.view.removeGestureRecognizer(navigationController!.interactivePopGestureRecognizer!)
    }

}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

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

}
2
David Seek

Je m'assure généralement que le glissement en arrière est activé dans le plus grand nombre d'endroits possible, même en ajoutant un outil de reconnaissance de mouvements personnalisé pour l'ajouter aux écrans modaux. Cependant, pour une authentification et un processus de téléchargement dans mon application, je lance le processus avec un contrôleur de navigation modal, puis envoie la vue à chaque étape suivante. Cependant, une fois terminé, je veux les empêcher de sauvegarder dans les écrans d'authentification.

Pour ce scénario, j'utilise:

navigationController?.interactivePopGestureRecognizer?.isEnabled = false
navigationItem.hidesBackButton = true

dans viewWillAppear() sur l'écran final. Vous pouvez les annuler dans viewWillDisappear() si vous insérez une autre vue et que vous en avez besoin.

2
blwinters

Si l'exigence est d'afficher le menu latéral sur certains écrans, ajoutez AddScreenEdgePanGesture sur cette vue spécifique au lieu de la vue navigationController.

remplacer

SideMenuManager.default.menuAddScreenEdgePanGesturesToPresent(toView: self.navigationController?.view)

avec ça

SideMenuManager.default.menuAddScreenEdgePanGesturesToPresent(toView: self.view)
0
Spydy

C'est quelque chose que vous avez manqué si cela ne fonctionne pas après avoir tout essayé.

  1. Ajouter navigationController?.interactivePopGestureRecognizer?.isEnabled = false à votre méthode viewWillAppear (animated :).
  2. si cela ne fonctionne pas, supprimez le délégué de navigation du contrôleur de vue. Vérifiez à nouveau si votre contrôleur de vue confirme les protocoles UINavigationControllerDelegate, UIGestureRecognizerDelegate. si oui, il suffit de l'enlever.
0
Li Jin