更新:我错了。实际上,您可以使用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