ios - InteractivePopGestureRecognizer causando la congelación de aplicaciones
objective-c (9)
En mi aplicación tengo diferentes controladores. Cuando presiono controlador1 al controlador de navegación y deslizo hacia atrás, todo funciona bien. Pero, si presiono el controlador de navegación1, y dentro del controlador1 presiono el controlador2 e intento deslizar hacia atrás obtengo una aplicación congelada. Si regresas a través del botón de retroceso todo funciona bien.
¿Cómo puedo detectar el problema?
Swift 4
Agregue este código al controlador de navegación raíz
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return self == self.navigationController?.topViewController ? false : true
}
Agregar el protocolo UIGestureRecognizerDelegate
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
Mi solución es intercambiar self.navigationController.interactivePopGestureRecognizer.delegate
entre selfImplementDelegate
y SystemDelegate
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[_tableView reloadData];
_oldReturnDelegate = self.navigationController.interactivePopGestureRecognizer.delegate;
self.navigationController.interactivePopGestureRecognizer.delegate = self;
}
- (void)viewWillDisappear:(BOOL)animated
{
self.navigationController.interactivePopGestureRecognizer.delegate = _oldReturnDelegate;
[super viewWillDisappear:animated];
}
Mi solución fue agregar un delegado al controlador de navegación. Luego deshabilite el reconocedor de gestos pop solo en el controlador de vista raíz. YMMV.
#pragma mark - UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
BOOL isRootVC = viewController == navigationController.viewControllers.firstObject;
navigationController.interactivePopGestureRecognizer.enabled = !isRootVC;
}
Swift 4:
Establecer el delegado,
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
Implementar el método delegado,
extension YourVC: UIGestureRecognizerDelegate{
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer && conditionToDisableTheGesture {
return false
}else{
return true
}
}
}
Te sugiero que pruebes esto. Esto funciona perfectamente para mi. Todavía se puede disfrutar de deslizamiento interactivo.
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)] &&
gestureRecognizer == self.navigationController.interactivePopGestureRecognizer) {
if(self.navigationController.viewControllers.count<=1)
{
return NO;
}
}
return YES;
}
Tuve el mismo problema y encontré la solución a continuación. agregar debajo del controlador
#import <UIKit/UIKit.h>
@interface CBNavigationController : UINavigationController <UIGestureRecognizerDelegate,UINavigationControllerDelegate>
@end
#import "CBNavigationController.h"
@interface CBNavigationController ()
@end
@implementation CBNavigationController
- (void)viewDidLoad
{
NSLog(@"%s",__FUNCTION__);
__weak CBNavigationController *weakSelf = self;
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
{
self.interactivePopGestureRecognizer.delegate = weakSelf;
self.delegate = weakSelf;
}
}
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
NSLog(@"%s",__FUNCTION__);
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
self.interactivePopGestureRecognizer.enabled = NO;
[super pushViewController:viewController animated:animated];
}
#pragma mark UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController
animated:(BOOL)animate
{
NSLog(@"%s",__FUNCTION__);
// Enable the gesture again once the new controller is shown
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
self.interactivePopGestureRecognizer.enabled = YES;
}
@end
Puede referirse a continuación enlace
http://keighl.com/post/ios7-interactive-pop-gesture-custom-back-button/
Tuve un problema al volver a deslizar el primer controlador y luego tocar en tableViewCell. Creo que la fuerza al tocar desde el borde está registrando el deslizamiento antes de que los interruptores de la aplicación, a veces la interfaz de usuario se atasque, a veces cuando vuelvo a deslizar comienza a ingresar en el controlador de destino. Resolví el problema con esta extensión, funcionó para mí y es una solución simple. Swift 4.2
extension UINavigationController:UINavigationControllerDelegate {
open override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
public func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
if responds(to: #selector(getter: self.interactivePopGestureRecognizer)) {
if viewControllers.count > 1 {
interactivePopGestureRecognizer?.isEnabled = true
} else {
interactivePopGestureRecognizer?.isEnabled = false
}
}
}
}
Tuve un problema similar con la interfaz de congelación al usar el gesto de deslizar para hacer estallar. En mi caso, el problema estaba en controller1.viewDidAppear Estaba deshabilitando el gesto de self.navigationController.interactivePopGestureRecognizer.enabled = NO
: self.navigationController.interactivePopGestureRecognizer.enabled = NO
. Entonces, cuando el usuario comenzó a deslizar hacia atrás desde contorller2, controller1.viewDidAppear se activó y el gesto se deshabilitó, justo durante su trabajo.
self.navigationController.interactivePopGestureRecognizer.delegate = self
esto configurando self.navigationController.interactivePopGestureRecognizer.delegate = self
en controller1 e implementando el gestureRecognizerShouldBegin:
de reconocimiento de gestos de gestureRecognizerShouldBegin:
lugar de desactivar el reconocedor de gestos:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)] &&
gestureRecognizer == self.navigationController.interactivePopGestureRecognizer) {
return NO;
}
return YES;
}
Resolví mi problema con UINavigationController interactivePopGestureRecognizer funcionando de manera anormal en iOS7 y configuré self.navigationController.interactivePopGestureRecognizer.delegate = self;
en cada controlador de vista - (void)viewWillAppear:(BOOL)animated