Обновление: я был неправ. Вы действительно можете использовать 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