В iOS 7 Apple добавила новое поведение навигации по умолчанию. Вы можете прокручивать левый край экрана, чтобы вернуться в стек навигации. Но в моем приложении это поведение конфликтует с моим пользовательским меню слева. Итак, можно ли отключить этот новый жест в UINavigationController?
Как отключить жест повторного салфетки в UINavigationController на iOS 7
Ответ 1
Я нашел решение:
Objective-C:
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
Swift 3: self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
Ответ 2
Я выяснил, что установка жестов для инвалидов только не всегда работает. Он работает, но для меня это произошло только после того, как я когда-то использовал заставку. Второй раз это не вызовет зарождение.
Исправить для меня было делегировать жест и реализовать метод shouldbegin для возврата 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;
}
Ответ 3
Просто удалите распознаватель жестов из NavigationController. Работа в iOS 8.
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)])
[self.navigationController.view removeGestureRecognizer:self.navigationController.interactivePopGestureRecognizer];
Ответ 4
Как и в iOS 8, принятый ответ больше не работает. Мне нужно было остановить разворот, чтобы убрать жест на моем главном экране игры, чтобы это реализовано:
- (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;
}
Ответ 5
Я немного уточнил Twan, потому что:
- ваш контроллер просмотра может быть установлен в качестве делегата для других распознавателей жестов.
- настройка делегата на
nil
приводит к зависанию при возврате к контроллеру корневого представления и делает жест жесткой передачи перед перемещением в другом месте.
В следующем примере предполагается 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;
}
Ответ 6
Пожалуйста, установите это в корневом каталоге vc:
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:YES];
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:YES];
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
}
Ответ 7
Для Swift:
navigationController!.interactivePopGestureRecognizer!.enabled = false
Ответ 8
ИЗМЕНИТЬ
Если вы хотите управлять функцией прокрутки назад для определенных навигационных контроллеров, рассмотрите возможность использования SwipeBack.
С помощью этого вы можете установить navigationController.swipeBackEnabled = NO
.
Например:
#import <SwipeBack/SwipeBack.h>
- (void)viewWillAppear:(BOOL)animated
{
navigationController.swipeBackEnabled = NO;
}
Он может быть установлен через CocoaPods.
pod 'SwipeBack', '~> 1.0'
Я извиняюсь из-за отсутствия объяснений.
Ответ 9
он работает для меня в ios 10 и более поздних версиях:
- (void)viewWillAppear:(BOOL)animated {
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
}
он не работает с методом viewDidLoad().
Ответ 10
Все эти решения манипулируют распознавателем жестов Apple так, как они не рекомендуют. Мне только что сказал друг, что есть лучшее решение:
[navigationController.interactivePopGestureRecognizer requireGestureRecognizerToFail: myPanGestureRecognizer];
где myPanGestureRecognizer - это распознаватель жестов, который вы используете, например, покажи свое меню. Таким образом, распознаватель жестов Apple не включается ими, когда вы нажимаете на новый контроллер навигации, и вам не нужно полагаться на случайные задержки, которые могут сработать слишком рано, если ваш телефон переведен в спящий режим или находится под большой нагрузкой.
Оставив это здесь, потому что я знаю, что я не запомню это в следующий раз, когда мне это понадобится, и тогда у меня будет решение проблемы здесь.
Ответ 11
Мой метод. Один распознаватель жестов, чтобы управлять всеми ними:
class DisabledGestureViewController: UIViewController: UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
navigationController!.interactivePopGestureRecognizer!.delegate = self
}
func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
// Prevent going back to the previous view
return !(navigationController!.topViewController is DisabledGestureViewController)
}
}
Важно: не reset делегат в любом месте стека навигации: navigationController!.interactivePopGestureRecognizer!.delegate = nil
Ответ 12
Это путь на Swift 3
работает для меня
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
Ответ 13
Это работает в viewDidLoad:
для iOS 8:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.navigationController.interactivePopGestureRecognizer.enabled = false;
});
Множество проблем можно было решить с помощью хорошего ol dispatch_after
.
Обратите внимание, что это решение потенциально небезопасно, пожалуйста, используйте свои собственные аргументы.
Обновление
Для iOS 8.1 время задержки должно составлять 0,5 секунды
В iOS 9.3 больше не требуется отсрочка, она работает просто, помещая это в свой viewDidLoad
:
(TBD, если работает на iOS 9.0-9.3)
navigationController?.interactivePopGestureRecognizer?.enabled = false
Ответ 14
Ни один из этих ответов не помог мне решить проблему. Проводя свой ответ здесь; может быть полезно для кого-то
Объявить private var popGesture: UIGestureRecognizer?
как глобальную переменную в вашем диспетчере просмотра. Затем выполните код в viewDidAppear и viewWillDisappear методы
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if self.navigationController!.respondsToSelector(Selector("interactivePopGestureRecognizer")) {
self.popGesture = navigationController!.interactivePopGestureRecognizer
self.navigationController!.view.removeGestureRecognizer(navigationController!.interactivePopGestureRecognizer!)
}
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
if self.popGesture != nil {
navigationController!.view.addGestureRecognizer(self.popGesture!)
}
}
Это отключит прокрутку обратно в iOS v8.x вперед
Ответ 15
Для Swift 4 это работает:
class MyViewController: UIViewController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.interactivePopGestureRecognizer?.gesture.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
self.navigationController?.interactivePopGestureRecognizer?.gesture.isEnabled = false
}
}
Ответ 16
У меня это работало для большинства контроллеров представления.
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
Это не работает для некоторых контроллеров представления, таких как UIPageViewController. На странице управления контентом UIPageViewController ниже код работал для меня.
override func viewDidLoad() {
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
}
override func viewWillDisappear(_ animated: Bool) {
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
self.navigationController?.interactivePopGestureRecognizer?.delegate = nil
}
На UIGestureRecognizerDelegate,
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer {
return false
}
return true
}