Cómo deshabilitar el gesto de deslizar hacia atrás en UINavigationController en iOS 7
En iOS 7, Apple agregó un nuevo comportamiento de navegación predeterminado. Puede deslizar el dedo desde el borde izquierdo de la pantalla para regresar a la pila de navegación. Pero en mi aplicación, este comportamiento entra en conflicto con mi menú izquierdo personalizado. Entonces, ¿es posible desactivar este nuevo gesto en UINavigationController?
Encontré una solución:
C objetivo:
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
Rápido 3+:
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
Descubrí que configurar el gesto solo como deshabilitado no siempre funciona. Funciona, pero para mí solo funcionó después de que usé una vez el gesto hacia atrás. La segunda vez no desencadenaría el gesto hacia atrás.
La solución para mí fue delegar el gesto e implementar el método debería comenzar para devolver 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;
}
Simplemente elimine el reconocedor de gestos de NavigationController. Trabajar en iOS 8.
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)])
[self.navigationController.view removeGestureRecognizer:self.navigationController.interactivePopGestureRecognizer];
A partir de iOS 8, la respuesta aceptada ya no funciona. Necesitaba detener el gesto de deslizar el dedo para descartar en la pantalla principal de mi juego, así que implementé esto:
- (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;
}
He refinado un poco la respuesta de Twan porque:
- su controlador de vista puede configurarse como delegado de otros reconocedores de gestos
- configurar el delegado
nil
genera problemas de bloqueo cuando regresa al controlador de vista raíz y hace un gesto de deslizar el dedo antes de navegar a otra parte.
El siguiente ejemplo supone 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;
}