Отключить жест, чтобы раскрыть модальное представление формы/страницы

В iOS 13 модальные презентации, использующие форму и стиль листа, могут быть отклонены жестом панорамирования. Это проблематично на одном из моих листов формы, потому что пользователь рисует в этом поле, которое мешает жесту. Он тянет экран вниз вместо рисования вертикальной линии.

Как вы можете отключить вертикальное движение, чтобы отклонить жест в контроллере модального представления, представленном в виде листа?

Установка isModalInPresentation = true прежнему позволяет isModalInPresentation = true лист, он просто не отклоняется.

Ответы

Ответ 1

В общем, для будущих интернет-путешественников не следует отключать свайп, чтобы отключить функциональность. Но если у вас есть сценарий, в котором эта функция влияет на ваши жесты или обработку касаний, я получил несколько советов от инженера Apple о том, как этого добиться.

Если вы можете предотвратить запуск средства распознавания жестов панорамирования системы, это предотвратит отклонение жеста. Несколько способов сделать это:

  1. Если рисование на холсте выполняется с помощью средства распознавания жестов, такого как ваш собственный подкласс UIGestureRecognizer, перейдите к фазе began, прежде чем жест отклонить листы. Если вы узнаете так же быстро, как UIPanGestureRecognizer, вы выиграете, и жест отклонения листов будет подорван.

  2. Если рисование на холсте выполняется с помощью распознавателя жестов, задайте требование динамического сбоя с помощью -shouldBeRequiredToFailByGestureRecognizer: (или связанного с ним метода делегата), в котором вы возвращаете NO, если переданный распознаватель жестов является UIPanGestureRecognizer.

  3. Если рисование на холсте выполнено с помощью ручной обработки касания (например, 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;
        }
    }
}