InteractivePopGestureRecognizer вызывает зависание приложения
В моем приложении у меня есть разные контроллеры. Когда я нажимаю контроллер1 на контроллер навигации и проведу назад, все работает хорошо. Но если я нажимаю навигационный контроллер1, а в контроллер1 нажимаю контроллер2 и пытаюсь провести назад, я получаю замороженное приложение. Если вернуться через кнопку назад, все работает нормально.
Как я могу поймать проблему?
6 ответов
У меня была похожая проблема с заморозкой интерфейса при использовании жестов смахивания. В моем случае проблема была в controller1.viewDidAppear. Я отключил жест смахивания: self.navigationController.interactivePopGestureRecognizer.enabled = NO
, Поэтому, когда пользователь начал смахивать назад с contorller2, controller1.viewDidAppear был запущен и жест был отключен, прямо во время его работы.
Я решил это, установив self.navigationController.interactivePopGestureRecognizer.delegate = self
в controller1 и реализации gestureRecognizerShouldBegin:
вместо отключения распознавателя жестов:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)] &&
gestureRecognizer == self.navigationController.interactivePopGestureRecognizer) {
return NO;
}
return YES;
}
Моим решением было добавить делегата в контроллер навигации. Затем отключите распознаватель поп-жестов только в корневом контроллере представления. YMMV.
#pragma mark - UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
BOOL isRootVC = viewController == navigationController.viewControllers.firstObject;
navigationController.interactivePopGestureRecognizer.enabled = !isRootVC;
}
У меня возникла проблема, когда снова проведите пальцем по первому контроллеру, а затем нажмите на tableViewCell. Я думаю, что принудительное касание с края регистрирует движение назад, прежде чем переключается приложение, иногда пользовательский интерфейс застревает, иногда, когда я поворачиваю назад, он начинает входить в целевой контроллер. Я решил проблему с этим расширением, у меня это сработало и это простое решение. 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
}
}
}
}
Свифт 4:
Установить делегата,
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
Реализуйте метод делегата,
extension YourVC: UIGestureRecognizerDelegate{
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer && conditionToDisableTheGesture {
return false
}else{
return true
}
}
}
Я бы предложил вам попробовать это. Это прекрасно работает для меня. Вы все еще можете наслаждаться интерактивным проведением.
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)] &&
gestureRecognizer == self.navigationController.interactivePopGestureRecognizer) {
if(self.navigationController.viewControllers.count<=1)
{
return NO;
}
}
return YES;
}
Мое решение - обмен self.navigationController.interactivePopGestureRecognizer.delegate
между selfImplementDelegate
а также 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];
}
Swift 4
Добавьте этот код в корневой контроллер навигации
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return self == self.navigationController?.topViewController ? false : true
}
Добавить протокол UIGestureRecognizerDelegate
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
У меня была такая же проблема, и я нашел решение ниже. добавить ниже контроллер
#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
См. Ссылку ниже
http://keighl.com/post/ios7-interactive-pop-gesture-custom-back-button/
Я решил свою проблему с помощью UINavigationController interactivePopGestureRecognizer, работающего ненормально в iOS7, и установил self.navigationController.interactivePopGestureRecognizer.delegate = self;
на каждом контроллере- (void)viewWillAppear:(BOOL)animated