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

Другие вопросы по тегам