我的方法与大多数人略有不同。我没有遍历视图集合以查找已isFirstResponder
设置的视图,而是向 发送消息nil
,但我存储了消息的接收者,以便我可以返回它并用它做任何我想做的事情。
import UIKit
private var _foundFirstResponder: UIResponder? = nil
extension UIResponder {
static var first:UIResponder? {
// Sending an action to 'nil' implicitly sends it to the first responder
// where we simply capture it and place it in the _foundFirstResponder variable.
// As such, the variable will contain the current first responder (if any) immediately after this line executes
UIApplication.shared.sendAction(#selector(UIResponder.storeFirstResponder(_:)), to: nil, from: nil, for: nil)
// The following 'defer' statement runs *after* this getter returns,
// thus releasing any strong reference held by the variable immediately thereafter
defer {
_foundFirstResponder = nil
}
// Return the found first-responder (if any) back to the caller
return _foundFirstResponder
}
@objc func storeFirstResponder(_ sender: AnyObject) {
// Capture the recipient of this message (self), which is the first responder
_foundFirstResponder = self
}
}
有了以上内容,我可以通过简单地这样做来辞去第一响应者的职务......
UIResponder.first?.resignFirstResponder()
但由于我的 API 实际上交还了第一响应者是什么,所以我可以用它做任何我想做的事情。
这是一个检查当前第一响应者是否UITextField
具有helpMessage
属性集的示例,如果是,则将其显示在控件旁边的帮助气泡中。我们通过屏幕上的“快速帮助”按钮调用它。
func showQuickHelp(){
if let textField = UIResponder?.first as? UITextField,
let helpMessage = textField.helpMessage {
textField.showHelpBubble(with:helpMessage)
}
}
对上述内容的支持是在UITextField
类似这样的扩展中定义的......
extension UITextField {
var helpMessage:String? { ... }
func showHelpBubble(with message:String) { ... }
}
现在要支持此功能,我们所要做的就是确定哪些文本字段有帮助消息,而 UI 会为我们处理剩下的事情。