Ответ 1
Изменение: я обновил этот ответ для iOS 12 и Swift. Пересмотренный пример проекта (содержащий новые реализации Swift и обновленные реализации Objective-C) находится здесь.
Вы можете создать новое окно UIWindow
и поместить его поверх окна по умолчанию, одновременно скрывая окно клавиатуры.
У меня есть пример проекта на Github здесь, но основной процесс ниже.
- Создайте новый класс
UIViewController
для вашего модального представления. Я назвал мойOverlayViewController
. Настройте соответствующий вид, как вы хотите. На ваш вопрос вам нужно передать некоторые опции, поэтому я создал протокол делегированияOverlayViewController
и сделаю контроллер корневого представления основного окна (классViewController
) нашим делегатом.
protocol OverlayViewControllerDelegate: class {
func optionChosen(option: YourOptionsEnum)
}
- Добавьте некоторые вспомогательные свойства в наш оригинальный контроллер вида.
class ViewController: UIViewController {
/// The text field that responds to a double-tap.
@IBOutlet private weak var firstField: UITextField!
/// A simple label that shows we received a message back from the overlay.
@IBOutlet private weak var label: UILabel!
/// The window that will appear over our existing one.
private var overlayWindow: UIWindow?
- Добавьте
UITapGestureRecognizer
в вашUITextField
.
override func viewDidLoad() {
super.viewDidLoad()
// Set up gesture recognizer
let doubleTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap))
doubleTapRecognizer.numberOfTapsRequired = 2
doubleTapRecognizer.delegate = self
firstField.addGestureRecognizer(doubleTapRecognizer)
firstField.becomeFirstResponder()
}
-
UITextField
имеет встроенный распознаватель жестов, поэтому нам нужно разрешить несколькимUIGestureRecognizer
работать одновременно.
extension ViewController: UIGestureRecognizerDelegate {
// Our gesture recognizer clashes with UITextField's.
// Need to allow both to work simultaneously.
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
- Это интересная часть. Когда распознаватель жестов сработает, создайте новое
OverlayViewController
UIWindow
, назначьте свойOverlayViewController
в качестве корневого контроллера представления и покажите его. Обратите внимание, что мы установили уровень окна наUIWindowLevelAlert
чтобы он отображался спереди. Тем не менее, клавиатура все еще будет впереди, несмотря на уровень окна предупреждения, поэтому мы должны также вручную скрыть ее окно.
Важно не устанавливать новое UIWindow
качестве клавиши или изменять первый респондент из UITextField
иначе клавиатура будет отклонена.
Ранее (до iOS 10?) Мы могли обойтись с overlayWindow.makeKeyAndVisible()
, но теперь установка его в качестве клавиши приведет к отключению клавиатуры. Кроме того, окно клавиатуры теперь имеет нестандартное значение UIWindow.Level
которое находится перед каждым публично определенным значением. Я работал над этим, находя окно клавиатуры в иерархии и скрывая его.
@objc func handleDoubleTap() {
// Prepare the overlay window
guard let overlayFrame = view?.window?.frame else { return }
overlayWindow = UIWindow(frame: overlayFrame)
overlayWindow?.windowLevel = .alert
let overlayVC = OverlayViewController.init(nibName: "OverlayViewController", bundle: nil)
overlayWindow?.rootViewController = overlayVC
overlayVC.delegate = self
// The keyboard window always appears to be the last in the hierarchy.
let keyboardWindow = UIApplication.shared.windows.last
keyboardWindow?.isHidden = true
}
- Окно наложения теперь является исходным окном. Теперь пользователь может выбрать любые параметры, встроенные в представление наложения. После того, как ваш пользователь выберет опцию, ваш делегат должен предпринять любое действие, которое вы запланировали, а затем закрыть окно наложения и снова показать клавиатуру.
func optionChosen(option: YourOptionsEnum) {
// Your code goes here. Take action based on the option chosen.
// ...
// Dismiss the overlay and show the keyboard
overlayWindow = nil;
UIApplication.shared.windows.last?.isHidden = false
}
- Оверлейное окно должно исчезнуть, и ваше исходное окно должно появиться с клавиатурой в том же положении, что и раньше.