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