Обновление: я был неправ. Вы действительно можете использовать UIApplication.shared.sendAction(_:to:from:for:)
для вызова первого респондента, показанного по этой ссылке: http://stackoverflow.com/a/14135456/746890 .
Большинство ответов здесь не могут найти текущего первого респондента, если он не находится в иерархии представлений. Например, AppDelegate
или UIViewController
подклассы.
Существует способ гарантировать его нахождение, даже если первый объект респондента не является UIView
.
Сначала давайте реализуем его обратную версию, используя next
свойство UIResponder
:
extension UIResponder {
var nextFirstResponder: UIResponder? {
return isFirstResponder ? self : next?.nextFirstResponder
}
}
С помощью этого вычисленного свойства мы можем найти текущего первого респондента снизу вверх, даже если это не так UIView
. Например, от оператора view
к тому, UIViewController
кто им управляет, если контроллер представления является первым респондентом.
Однако нам все еще нужно разрешение сверху вниз, единственное, var
чтобы получить текущий первый респондент.
Сначала с иерархией представления:
extension UIView {
var previousFirstResponder: UIResponder? {
return nextFirstResponder ?? subviews.compactMap { $0.previousFirstResponder }.first
}
}
Он будет искать первого респондента в обратном направлении, и если он не сможет его найти, он скажет своим подпредставлениям сделать то же самое (потому что его подпредставление next
не обязательно само по себе). При этом мы можем найти его с любой точки зрения, в том числе UIWindow
.
И, наконец, мы можем построить это:
extension UIResponder {
static var first: UIResponder? {
return UIApplication.shared.windows.compactMap({ $0.previousFirstResponder }).first
}
}
Поэтому, когда вы хотите получить первого респондента, вы можете позвонить:
let firstResponder = UIResponder.first