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

iOS 13 представляет новый modalPresentationStyle для модально представленных контроллеров представления…

… И его можно отклонить, сдвинув представленный контроллер представления вниз (интерактивное отклонение). Даже несмотря на то, что новая функция смахивания к отклонению довольно полезна, она не всегда может быть желательной. Итак, вопрос в следующем:

Как мы можем отключить интерактивное увольнение? - Имейте в виду, он включен по умолчанию.

10 ответов

Решение

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

Если trueUIKit игнорирует события вне границ контроллера представления и предотвращает интерактивное отключение контроллера представления, пока он находится на экране. По умолчанию false,

~ Официальная бета-версия modalInPresentation вкратце.

  1. Если вы хотите использовать то же поведение, что и в предыдущей версии 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 и ранее (отключение отключения представленного контроллера представления), вы можете сделать следующее:

    1. Убедитесь, что контроллер представления, ответственный за представление нового контроллера представления, соответствует UIAdaptivePresentationControllerDelegate

    2. Позвоните в presentationControllerShouldDismiss функция и возврат false.

    Итак, (1) и (2) могут быть легко реализованы путем добавления следующего расширения к контроллеру представления, отвечающему за представление нового контроллера представления:

          extension LoginViewController: UIAdaptivePresentationControllerDelegate {
        func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
            return false
        }
    }
    
    1. Перед представлением нового контроллера представления обязательно установите делегат (в этом примере предполагается, что новый контроллер встроен в контроллер навигации):

      navigationController.presentationController?.delegate = self

    Я так старался решить эту проблему, но для меня решение работает: я выбираю ViewController в **основной раскадровке > инспектор > презентация > Полноэкранный режим ** по умолчанию Автоматически для изменения полноэкранного режима

    для меня это работа

    Все решения хороши, но в моем случае нужна возможность остановки движения. Так что это код для этого.

    если вы хотите заблокировать движение:

          self.yourViewController?.presentedView?.gestureRecognizers?[0].isEnabled = false
    

    И если вы хотите разблокировать движение:

          self.yourViewController?.presentedView?.gestureRecognizers?[0].isEnabled = true
    
    Другие вопросы по тегам