Отключить жест, чтобы раскрыть модальное представление формы/страницы
В iOS 13 модальные презентации, использующие форму и стиль листа, могут быть отклонены жестом панорамирования. Это проблематично на одном из моих листов формы, потому что пользователь рисует в этом поле, которое мешает жесту. Он тянет экран вниз вместо рисования вертикальной линии.
Как вы можете отключить вертикальное движение, чтобы отклонить жест в контроллере модального представления, представленном в виде листа?
Установка isModalInPresentation = true
прежнему позволяет isModalInPresentation = true
лист, он просто не отклоняется.
Ответы
Ответ 1
В общем, для будущих интернет-путешественников не следует отключать свайп, чтобы отключить функциональность. Но если у вас есть сценарий, в котором эта функция влияет на ваши жесты или обработку касаний, я получил несколько советов от инженера Apple о том, как этого добиться.
Если вы можете предотвратить запуск средства распознавания жестов панорамирования системы, это предотвратит отклонение жеста. Несколько способов сделать это:
Если рисование на холсте выполняется с помощью средства распознавания жестов, такого как ваш собственный подкласс UIGestureRecognizer
, перейдите к фазе began
, прежде чем жест отклонить листы. Если вы узнаете так же быстро, как UIPanGestureRecognizer
, вы выиграете, и жест отклонения листов будет подорван.
Если рисование на холсте выполняется с помощью распознавателя жестов, задайте требование динамического сбоя с помощью -shouldBeRequiredToFailByGestureRecognizer:
(или связанного с ним метода делегата), в котором вы возвращаете NO
, если переданный распознаватель жестов является UIPanGestureRecognizer
.
Если рисование на холсте выполнено с помощью ручной обработки касания (например, touchesBegan:
), переопределите -gestureRecognizerShouldBegin
в представлении обработки касания и верните NO
, если переданный распознаватель жестов является UIPanGestureRecognizer
.
С моей настройкой # 3 оказалось очень хорошо работать. Это позволяет пользователю смахнуть вниз за пределы холста для рисования (например, панель навигации), одновременно позволяя рисовать без перемещения листа, как и следовало ожидать.
Я не могу рекомендовать попытаться найти жест, чтобы отключить его, так как он кажется довольно динамичным и может повторно включаться при переключении между классами разных размеров, например, и это может измениться в будущих выпусках.
Ответ 2
Этот жест можно найти в свойстве контроллера модального представления presentedView
. Когда я отлаживал, массив gestureRecognizers
этого свойства содержит только один элемент, и его печать выглядела примерно так:
UIPanGestureRecognizer: 0x7fd3b8401aa0
(_UISheetInteractionBackgroundDismissRecognizer);
Таким образом, чтобы отключить этот жест, вы можете сделать, как показано ниже:
let vc = UIViewController()
self.present(vc, animated: true, completion: {
vc.presentationController?.presentedView?.gestureRecognizers?[0].isEnabled = false
})
Чтобы включить его, просто установите isEnabled
обратно на true
:
vc.presentationController?.presentedView?.gestureRecognizers?[0].isEnabled = true
Обратите внимание, что iOS 13 все еще находится в бета-версии, поэтому в следующем выпуске может быть добавлен более простой подход.
Хотя это решение, кажется, работает в данный момент, я бы не рекомендовал его, поскольку оно может не работать в некоторых ситуациях или может быть изменено в будущих выпусках iOS и, возможно, повлияет на ваше приложение.
Ответ 3
В представленном ViewController используйте это в viewDidLoad:
if #available(iOS 13.0, *) {
self.isModalInPresentation = true
}
Ответ 4
Вы можете изменить стиль презентации, если в полноэкранном режиме отключить раскрывающееся меню
navigationCont.modalPresentationStyle = .fullScreen
Ответ 5
Для навигации по Контроллеру, чтобы избежать смахивания для представленного представления, мы можем использовать:
if #available(iOS 13.0, *) {navController.isModalInPresentation = true}
Ответ 6
Вы можете использовать метод UIAdaptivePresentationControllerDelegate presentationControllerDidAttemptToDismiss и отключить gestRecognizer для представленного представления.
Примерно так:
func presentationControllerDidAttemptToDismiss(_ presentationController: UIPresentationController) {
presentationController.presentedView?.gestureRecognizers?.first?.isEnabled = false
}
Ответ 7
Я использую это:
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
for(UIGestureRecognizer *gr in self.presentationController.presentedView.gestureRecognizers) {
if (@available(iOS 11.0, *)) {
if([gr.name isEqualToString:@"_UISheetInteractionBackgroundDismissRecognizer"]) {
gr.enabled = false;
}
}
}