Оновлення: я помилявся. Ви дійсно можете використовувати 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. Наприклад, від a viewдо theUIViewController хто ним керує, якщо контролер перегляду є першим відповіддю.
Однак нам все ще потрібна роздільна здатність зверху вниз, одинарна, 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