更新:私は間違っていました。確かに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