Отключить интерактивное увольнение в iOS 13
iOS 13 представляет новый modalPresentationStyle
для модально представленных контроллеров представления…
… И его можно отклонить, сдвинув представленный контроллер представления вниз (интерактивное отклонение). Даже несмотря на то, что новая функция смахивания к отклонению довольно полезна, она не всегда может быть желательной. Итак, вопрос в следующем:
Как мы можем отключить интерактивное увольнение? - Имейте в виду, он включен по умолчанию.
10 ответов
UIViewController
содержит новое свойство под названием isModalInPresentation
который должен быть установлен в true
предотвратить интерактивное увольнение.
Если
true
UIKit игнорирует события вне границ контроллера представления и предотвращает интерактивное отключение контроллера представления, пока он находится на экране. По умолчаниюfalse
,~ Официальная бета-версия modalInPresentation вкратце.
Если вы хотите использовать то же поведение, что и в предыдущей версии IOS (
UIModalPresentationStyle.fullScreen
let someViewController = \*VIEW CONTROLLER*\
someViewController.modalPresentationStyle = .fullScreen
И если вы используете раскадровку, просто выберите Segua и выберите Full Screen
сформировать Presentation
падать.
Если вы просто хотите отключить интерактивное увольнение и оставить новый стиль презентации установленным UIViewController
свойство isModalInPresentation
в true
,
if #available(iOS 13.0, *) {
someViewController.isModalInPresentation = true // available in IOS13
}
Недвижимость isModalInPresentation
может помочь.
Из документации:
Когда вы установите его на
true
, UIKit игнорирует события за пределами границ контроллера представления и предотвращает интерактивное отключение контроллера представления, когда он находится на экране.
Вы можете использовать это так:
let controller = MyViewController()
controller.isModalInPresentation = true
self.present(controller, animated: true, completion: nil)
Если у вас есть какая-то бизнес-логика, что-то вроде того, что все поля должны быть заполнены перед увольнением, вам следует:
На
ViewDidLoad
если ваш ViewController является родительским элементом контроллера навигации:
func viewDidLoad() {
self.navigationController?.presentationController?.delegate = self
}
Если нет, просто используйте
func viewDidLoad() {
self.presentationController?.delegate = self
}
Затем реализуйте метод делегата:
extension ViewController: UIAdaptivePresentationControllerDelegate {
func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
guard let text = firstName.text, text.isEmpty else { return false }
guard let text = lastName.text, text.isEmpty else { return false }
...
return true
}
}
Если вы используете раскадровки для макета своего пользовательского интерфейса, я нашел лучший способ отключить это интерактивное отклонение при использовании контроллера навигации - это изменить представление контроллера навигации в инспекторе атрибутов с автоматического на полноэкранный. После этого все контроллеры представлений в стеке навигации будут работать в полноэкранном режиме, и пользователь не сможет их закрыть.
Инспектор атрибутов, показывающий вариант представления для контроллера навигации
Теперь вы можете реализовать делегат для распознавателя жестов взаимодействия и отключить взаимодействие, если есть попытка одновременно взаимодействовать с ползунком. Таким образом, вы сохраните интерактивное закрытие, а ползунок будет работать должным образом.
Вы можете отключить свайп вниз вот так:
let controller = storyboard?.instantiateViewController(withIdentifier: "NextVC") as! NextVC
let navigationController = UINavigationController(rootViewController: controller)
self.present(navigationController, animated: true, completion: {
navigationController.presentationController?.presentedView?.gestureRecognizers?[0].isEnabled = false
})
Apple поделилась образцом кода по этой ссылке
Оно использует isModalInPresentation
как предлагают многие пользователи.
Для тех, кто хочет добиться этого в iOS 12 и ранее (отключение отключения представленного контроллера представления), вы можете сделать следующее:
Убедитесь, что контроллер представления, ответственный за представление нового контроллера представления, соответствует
UIAdaptivePresentationControllerDelegate
Позвоните в
presentationControllerShouldDismiss
функция и возвратfalse
.
Итак, (1) и (2) могут быть легко реализованы путем добавления следующего расширения к контроллеру представления, отвечающему за представление нового контроллера представления:
extension LoginViewController: UIAdaptivePresentationControllerDelegate {
func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
return false
}
}
Перед представлением нового контроллера представления обязательно установите делегат (в этом примере предполагается, что новый контроллер встроен в контроллер навигации):
navigationController.presentationController?.delegate = self
Я так старался решить эту проблему, но для меня решение работает: я выбираю ViewController в **основной раскадровке > инспектор > презентация > Полноэкранный режим ** по умолчанию Автоматически для изменения полноэкранного режима
для меня это работа
Все решения хороши, но в моем случае нужна возможность остановки движения. Так что это код для этого.
если вы хотите заблокировать движение:
self.yourViewController?.presentedView?.gestureRecognizers?[0].isEnabled = false
И если вы хотите разблокировать движение:
self.yourViewController?.presentedView?.gestureRecognizers?[0].isEnabled = true