Pembaruan: Saya salah. Anda memang dapat menggunakan UIApplication.shared.sendAction(_:to:from:for:)
untuk memanggil responden pertama yang ditunjukkan dalam tautan ini: http://stackoverflow.com/a/14135456/746890 .
Sebagian besar jawaban di sini tidak dapat benar-benar menemukan responden pertama saat ini jika tidak ada dalam hierarki tampilan. Misalnya, AppDelegate
atau UIViewController
subclass.
Ada cara untuk menjamin Anda menemukannya meskipun objek responden pertama bukan a UIView
.
Pertama mari kita terapkan versi yang dibalik darinya, menggunakan next
properti dari UIResponder
:
extension UIResponder {
var nextFirstResponder: UIResponder? {
return isFirstResponder ? self : next?.nextFirstResponder
}
}
Dengan properti yang dihitung ini, kami dapat menemukan responden pertama saat ini dari bawah ke atas walaupun itu tidak UIView
. Misalnya, dari a view
keUIViewController
siapa yang mengelolanya, jika pengontrol tampilan adalah responden pertama.
Namun, kami masih membutuhkan resolusi top-down, satu var
untuk mendapatkan responden pertama saat ini.
Pertama dengan hierarki tampilan:
extension UIView {
var previousFirstResponder: UIResponder? {
return nextFirstResponder ?? subviews.compactMap { $0.previousFirstResponder }.first
}
}
Ini akan mencari responden pertama mundur, dan jika tidak dapat menemukannya, ia akan memberi tahu subview untuk melakukan hal yang sama (karena subviewnya next
tidak harus dengan sendirinya). Dengan ini kita dapat menemukannya dari tampilan apa pun, termasuk UIWindow
.
Dan akhirnya, kita dapat membangun ini:
extension UIResponder {
static var first: UIResponder? {
return UIApplication.shared.windows.compactMap({ $0.previousFirstResponder }).first
}
}
Jadi ketika Anda ingin mengambil responden pertama, Anda dapat menghubungi:
let firstResponder = UIResponder.first