私は他の人とは少し違うアプローチをしています。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が処理してくれます。