Отключить интерактивное закрытие представленного контроллера представления в iOS 13

135

iOS 13 представляет новый дизайн modalPresentationStyle .pageSheet(и его родственника .formSheet) для модально представленных контроллеров представления…

Новая скользящая модальная презентация в iOS 13

… И мы можем отклонить эти листы, сдвинув представленный контроллер представления вниз (интерактивное отклонение) . Хотя новая функция «потянуть и закрыть» довольно полезна, она не всегда может быть желательной.

ВОПРОС: Как отключить интерактивное увольнение? - Имейте в виду, что мы сохраняем стиль презентации.

Якуб Трухларж
источник
4
Возможный дубликат представления модального
окна в
6
@MehulThakkar Это другой вопрос.
Якуб Трухларж

Ответы:

241

Опция 1:

viewController.isModalInPresentation = true

Отключено интерактивное увольнение

(Отключенное интерактивное .pageSheetувольнение действует так.)

  • Начиная с iOS 13, UIViewControllerсодержит новое свойство с именем, isModalInPresentationкоторое необходимо установить trueдля предотвращения интерактивного увольнения.
  • Он в основном игнорирует события вне границ контроллера представления. Имейте это в виду, если вы используете не только автоматический стиль, но и такие стили презентации, как .popoverи т. Д.
  • Это свойство falseпо умолчанию.

Из официальных документов : If true, UIKit игнорирует события за пределами границ контроллера представления и предотвращает интерактивное закрытие контроллера представления, пока он находится на экране.


Вариант 2:

func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
    return false
}
  • Начиная с iOS 13, UIAdaptivePresentationControllerDelegateсодержит новый метод с именем presentationControllerShouldDismiss.
  • Этот метод вызывается только в том случае, если представленный контроллер представления не отклонен программно и для его isModalInPresentationсвойства установлено значение false.

Совет: не забудьте назначить делегата presentationController.

Якуб Трухларж
источник
2
Если представленный контроллер представления является контроллером навигации, вы можете установить его либо isModalInPresentationна контроллере навигации, либо на отдельных контроллерах представления, показанных в стеке навигации. Последний позволяет вам по очереди выбирать, возможно ли интерактивное увольнение. Осторожно с контроллерами поиска, они имеют приоритет над отдельным контроллером представления (но не контроллером навигации). Более подробная информация в моем сообщении в блоге: medium.com/@hacknicity/…
Джефф
1
Имейте в виду, что если ваш VC представлен как всплывающее окно, это предотвратит закрытие всплывающего окна при нажатии за его пределами
PatrickDotStar
4
Objective-C:viewController.modalInPresentation = YES;
quarac 01
3
Кто-нибудь заставил это работать при установке этого флага на UIImagePickerController? Для нас это выглядит так, как будто UIImagePickerControllerон игнорирует это, и поэтому его можно закрыть жестом смахивания. Может это ошибка iOS 13.
PatrickDotStar
4
Когда presentationControllerShouldDismiss(_ presentationController: UIPresentationController)возвращается false, presentationControllerDidAttemptToDismiss(_ presentationController: UIPresentationController)вызывается, чтобы вы могли делать такие вещи, как добавление диалогового окна подтверждения, если пользователь ввел данные.
Нил
66
  1. Если вам нужно такое же поведение, как в предыдущей версии iOS (<iOS13), например, представление модели в полноэкранном режиме, просто установите стиль представления вашего целевого контроллера представления на UIModalPresentationStyle.fullScreen

    let someViewController = \*VIEW CONTROLLER*\
    someViewController.modalPresentationStyle = .fullScreen

    А если вы используете раскадровку, просто выберите сегуа и выберите Full Screenиз Presentationраскрывающегося списка.

    введите описание изображения здесь

  2. Если вы просто хотите отключить интерактивное увольнение и оставить для UIViewControllerсвойства нового стиля презентации isModalInPresentationзначение true.

    if #available(iOS 13.0, *) {
        someViewController.isModalInPresentation = true // available in IOS13
    }
Билал
источник
Это работает лучше, чем использование {controller.isModalInPresentation = true}.
Максим Фирсофф
8

Собственность isModalInPresentationможет помочь.

Из документации:

Когда вы устанавливаете это значение true, UIKit игнорирует события за пределами границ контроллера представления и предотвращает интерактивное отключение контроллера представления, когда он находится на экране.

Вы можете использовать это так:

let controller = MyViewController()
controller.isModalInPresentation = true
self.present(controller, animated: true, completion: nil)
Мохит Томар
источник
5

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

Инспектор атрибутов, показывающий вариант представления для контроллера навигации

Брэндон Уиттон
источник
1

Apple поделилась образцом кода по этой ссылке

Он использует isModalInPresentationкак можно больше предложений пользователей.

Арда Огул Учпинар
источник