Отключение back swipe gesture для UINavigation Controller

Начиная с IOS 7 ввели прикольную фишку для UINavigation Controller’a — возможность «смахнуть» текущий UIView к предыдущему жестом от края  к центру экрана. В оригинале звучит как back swipe gesture. Но не всем она по душе и все адаптируют контроллеры под данное поведение. Под катом будем отключать данное поведение.

Navigation Controller Back Swipe Gesture

Создаем тестовый проект со следующей схемой. Корневой Navigation контроллер и два UIView. На зеленом контролере есть кнопка для перехода на оранжевый. Поведение вы видите на gif’ке выше.

Снимок экрана 2016-04-07 в 20.28.19

Отключение

Согласно документации у UINavigationController есть readonly свойство interactivePopGestureRecognizer, который отвечает за «выталкивание» UIViewController’ов из стека. У него в свою очередь есть флаг enabled, который отвечает за распознавание жестов.

Сабкласнем UINavigationController и попытаемся отключить распознавание жестов. Это можно делать и в UIViewController’ах, но сабкласс удобнее, если у вас не один storyboard  и не один navigation controller.

#import "UINavigationControllerBackSwipeGestureDisabled.h"

@interface UINavigationControllerBackSwipeGestureDisabled ()

@end

@implementation UINavigationControllerBackSwipeGestureDisabled

- (void)viewDidLoad {
    [super viewDidLoad];
    // Выключение back swipe gesture
    self.interactivePopGestureRecognizer.enabled = NO;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Пробуем — работает. Жесты отключились. Теперь назад только через кнопку «Назад».

navbackswipedisabled

Для контролеров страницы это выглядело бы так:

self.navigationController.interactivePopGestureRecognizer.enabled = NO;

Delegate?

Но если посмотреть ответы на stackoverflow, то там еще манипулируют делегатом.

self.navigationController.interactivePopGestureRecognizer.delegate = nil;

или

self.navigationController.interactivePopGestureRecognizer.delegate = self;


- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    return NO;
}

Это требуется если вы используете какие-нибудь сторонние библиотеки а-ля MFSideMenu и другие, которые используют UIGestureRecognizerDelegate.

Там уже надо смотреть по коду и корректно управлять делегатом.

Добавить комментарий