bar ios objective-c uinavigationcontroller uinavigationbar uinavigationitem

ios - ¿Cómo habilitar el gesto de deslizamiento hacia atrás/izquierda en UINavigationController después de configurar leftBarButtonItem?



navigation bar ios 11 (9)

Tengo el problema opuesto desde here . De forma predeterminada en iOS7 , el gesto de deslizar hacia atrás de la pila de UINavigationController podría UINavigationController el ViewController presentado. Ahora acabo de uniformar todo el estilo self.navigationItem.leftBarButtonItem para todos los ViewControllers .

Aquí está el código:

self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:LOADIMAGE(@"back_button") style:UIBarButtonItemStylePlain target:self action:@selector(popCurrentViewController)];

después de eso, navigationController.interactivePopGestureRecognizer está deshabilitado. ¿Cómo podría habilitar el gesto pop sin eliminar el leftBarButtonItem personalizado?

¡Gracias!


A mí me funciona cuando configuro el delegado

self.navigationController.interactivePopGestureRecognizer.delegate = self;

y luego implementar

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES; }


Esta es la mejor manera de habilitar / deshabilitar el deslizamiento al controlador de vista emergente en iOS 10, Swift 3 :

Para la primera pantalla [donde desea desactivar el gesto de deslizar]:

class SignUpViewController : UIViewController,UIGestureRecognizerDelegate { //MARK: - View initializers override func viewDidLoad() { super.viewDidLoad() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) swipeToPop() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } func swipeToPop() { self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true; self.navigationController?.interactivePopGestureRecognizer?.delegate = self; } func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer { return false } return true } }

Para la pantalla central [donde desea habilitar el gesto de deslizar]:

class FriendListViewController : UIViewController { //MARK: - View initializers override func viewDidLoad() { super.viewDidLoad() swipeToPop() } func swipeToPop() { self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true; self.navigationController?.interactivePopGestureRecognizer?.delegate = nil; } }


Establecer un botón de retroceso personalizado deshabilita la función de deslizar hacia atrás.

Lo mejor que puede hacer para mantenerlo es subclasificar UINavigationViewController y establecerse como el delegado interactivePopGestureRecognizer ; entonces puede devolver SÍ desde gestureRecognizerShouldBegin para permitir el deslizamiento hacia atrás.

Por ejemplo, esto se hace en https://github.com/fastred/AHKNavigationController

Y una versión Swift aquí: https://.com/a/43433530/308315


Necesita manejar dos escenarios:

  1. Cuando empujas una nueva vista a la pila
  2. Cuando muestra el controlador de vista raíz

Si solo necesita una clase base que pueda usar, aquí hay una versión de Swift 3:

import UIKit final class SwipeNavigationController: UINavigationController { // MARK: - Lifecycle override init(rootViewController: UIViewController) { super.init(rootViewController: rootViewController) } override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) delegate = self } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) delegate = self } override func viewDidLoad() { super.viewDidLoad() // This needs to be in here, not in init interactivePopGestureRecognizer?.delegate = self } deinit { delegate = nil interactivePopGestureRecognizer?.delegate = nil } // MARK: - Overrides override func pushViewController(_ viewController: UIViewController, animated: Bool) { duringPushAnimation = true super.pushViewController(viewController, animated: animated) } // MARK: - Private Properties fileprivate var duringPushAnimation = false } // MARK: - UINavigationControllerDelegate extension SwipeNavigationController: UINavigationControllerDelegate { func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) { guard let swipeNavigationController = navigationController as? SwipeNavigationController else { return } swipeNavigationController.duringPushAnimation = false } } // MARK: - UIGestureRecognizerDelegate extension SwipeNavigationController: UIGestureRecognizerDelegate { func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { guard gestureRecognizer == interactivePopGestureRecognizer else { return true // default value } // Disable pop gesture in two situations: // 1) when the pop animation is in progress // 2) when user swipes quickly a couple of times and animations don''t have time to be performed return viewControllers.count > 1 && duringPushAnimation == false } }

Si termina necesitando actuar como un UINavigationControllerDelegate en otra clase, puede escribir un reenviador de delegado similar a esta respuesta .

Adaptado de la fuente en Objective-C: https://github.com/fastred/AHKNavigationController


Para aquellos que todavía tienen problemas con esto, intente separar las dos líneas como se muestra a continuación.

override func viewDidLoad() { self.navigationController!.interactivePopGestureRecognizer!.delegate = self ... override func viewWillAppear(_ animated: Bool) { self.navigationController!.interactivePopGestureRecognizer!.isEnabled = true ...

Obviamente, en mi aplicación,

interactivePopGestureRecognizer! .isEnabled

se restableció a false antes de que la vista se mostrara por alguna razón.


Primer conjunto delegado en viewDidLoad:

self.navigationController.interactivePopGestureRecognizer.delegate = self;

Y luego deshabilita el gesto al presionar:

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { [super pushViewController:viewController animated:animated]; self.interactivePopGestureRecognizer.enabled = NO; }

Y habilitar en viewDidDisappear:

self.navigationController.interactivePopGestureRecognizer.enabled = YES;

Además, agregue UINavigationControllerDelegate a su controlador de vista.


Swift 3:

override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.navigationController?.interactivePopGestureRecognizer?.delegate = self } func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true } func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool { return (otherGestureRecognizer is UIScreenEdgePanGestureRecognizer) }


me funciona Swift 3 :

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true }

y en ViewDidLoad:

self.navigationController?.interactivePopGestureRecognizer?.delegate = self self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true


This respuesta, pero con soporte de guión gráfico.

class SwipeNavigationController: UINavigationController { // MARK: - Lifecycle override init(rootViewController: UIViewController) { super.init(rootViewController: rootViewController) } override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) self.setup() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.setup() } private func setup() { delegate = self } override func viewDidLoad() { super.viewDidLoad() // This needs to be in here, not in init interactivePopGestureRecognizer?.delegate = self } deinit { delegate = nil interactivePopGestureRecognizer?.delegate = nil } // MARK: - Overrides override func pushViewController(_ viewController: UIViewController, animated: Bool) { duringPushAnimation = true super.pushViewController(viewController, animated: animated) } // MARK: - Private Properties fileprivate var duringPushAnimation = false }