Jak wyłączyć gest przesunięcia z powrotem w UINavigationController na iOS 7

W systemie iOS 7 Apple dodało nowe domyślne zachowanie nawigacji. Możesz przesuwać palcem od lewej krawędzi ekranu, aby wrócić do stosu nawigacji. Ale w mojej aplikacji to zachowanie jest sprzeczne z moim niestandardowym lewym menu. Tak, jest to możliwe, aby wyłączyć ten nowy gest w UINavigationController?

Author: hfossli, 2013-06-20

15 answers

Znalazłem rozwiązanie:

Objective-C:

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

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

 541
Author: ArtFeel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-15 09:25:11

Okazało się, że ustawienie gest tylko wyłączone nie zawsze działa. To działa, ale dla mnie to tylko po raz użył backgesture. Za drugim razem nie wywołałoby to odwrotu.

Fix dla mnie było delegowanie gestu i implementacja metody shouldbegin, aby zwrócić NO:

- (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;
}
 44
Author: Antoine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-24 14:28:32

Po prostu usuń rozpoznawanie gestów z NavigationController. Praca w iOS 8.

if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)])
    [self.navigationController.view removeGestureRecognizer:self.navigationController.interactivePopGestureRecognizer];
 26
Author: Vladimir Samoylov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-21 10:01:57

Od iOS 8 zaakceptowana odpowiedź nie działa. Musiałem zatrzymać przesuwanie, aby odrzucić gest na głównym ekranie gry, więc zaimplementowałem to:

- (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
Author: Charlie Seligman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-01 17:50:52

Trochę dopracowałem odpowiedź Twana, ponieważ:

  1. Twój kontroler widoku może być ustawiony jako delegat dla innych rozpoznawaczy gestów
  2. Ustawienie delegata na nil prowadzi do problemów z zawieszeniem, Gdy wrócisz do kontrolera widoku głównego i wykonasz gest machnięcia przed nawigacją w innym miejscu.

Poniższy przykład zakłada 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;
}
 17
Author: Ja͢ck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-17 04:12:11

EDIT

Jeśli chcesz zarządzać funkcją przesuń w tył dla określonych kontrolerów nawigacyjnych, rozważ użycie Przesuń w tył.

Za pomocą tego możesz ustawić navigationController.swipeBackEnabled = NO.

Na przykład:

#import <SwipeBack/SwipeBack.h>

- (void)viewWillAppear:(BOOL)animated
{
    navigationController.swipeBackEnabled = NO;
}
[[5]} można go zainstalować za pomocą CocoaPods .
pod 'SwipeBack', '~> 1.0'

Apologizuję z braku wyjaśnienia.

 7
Author: devxoul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-06 04:42:20

Proszę ustawić to w 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;
}
 6
Author: reza_khalafi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-04 05:43:34

U mnie działa w ios 10 i nowszych :

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

}

Nie działa przy metodzie viewDidLoad ().

 5
Author: Logic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-03 10:23:27

Dla Swift:

navigationController!.interactivePopGestureRecognizer!.enabled = false
 4
Author: iPhone 7,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-06 04:41:53

Żadna z udzielonych odpowiedzi nie pomogła mi rozwiązać problemu. Zamieszczanie tutaj mojej odpowiedzi; może być pomocne dla kogoś

Zadeklaruj private var popGesture: UIGestureRecognizer? jako zmienną globalną w kontrolerze viewcontroller. Następnie zaimplementuj kod w metodach viewdidappear i 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!)
    }
}

To wyłączy przesunięcie z powrotem w iOS v8.x

 2
Author: Augustine P A,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-05 11:54:46

To działa w viewDidLoad: dla 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;
  });

Wiele problemów można rozwiązać przy pomocy starego dobrego dispatch_after.

Chociaż proszę pamiętać, że to rozwiązanie jest potencjalnie niebezpieczne, Proszę użyć własnego rozumowania.

Update

Dla systemu iOS 8.1 czas opóźnienia powinien wynosić 0,5 sekundy

Na iOS 9.3 nie trzeba już opóźniać, działa po prostu umieszczając to w swoim viewDidLoad: W tym celu należy skontaktować się z działem obsługi klienta.]}
navigationController?.interactivePopGestureRecognizer?.enabled = false
 2
Author: Dannie P,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-12 12:56:26

Wszystkie te rozwiązania manipulują rozpoznawaniem gestów Apple w sposób, którego nie zalecają. Znajomy mi właśnie powiedział, że jest lepsze rozwiązanie:

[navigationController.interactivePopGestureRecognizer requireGestureRecognizerToFail: myPanGestureRecognizer];

Gdzie myPanGestureRecognizer jest rozpoznawaczem gestów, którego używasz np. do wyświetlania menu. W ten sposób funkcja rozpoznawania gestów Apple nie zostanie ponownie włączona po naciśnięciu nowego kontrolera nawigacyjnego i nie musisz polegać na skandalicznych opóźnieniach, które mogą odpalić się zbyt wcześnie, jeśli telefon jest uśpiony lub pod ciężki ładunek.

Zostawiam to tutaj, ponieważ Wiem, że nie będę tego pamiętać następnym razem, gdy będę tego potrzebował, a potem będę miał rozwiązanie problemu tutaj.

 2
Author: uliwitness,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-26 14:16:30

Moja metoda. Jeden gest, by rządzić nimi wszystkimi:

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

Ważne: nie Resetuj delegata w dowolnym miejscu stosu nawigacji: navigationController!.interactivePopGestureRecognizer!.delegate = nil

 2
Author: SoftDesigner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-28 08:55:08

This is the way on Swift 3

Działa dla mnie

    self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
 2
Author: Tayo119,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-13 11:50:04

Dla Swift 4 to działa:

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 = true
    }

}
 1
Author: Mat0,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-20 15:01:41