У меня немного другой подход, чем у большинства здесь. Вместо того, чтобы перебирать коллекцию представлений в поисках того, для которого установлено 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 for return
UIApplication.shared.sendAction(#selector(UIResponder.storeFirstResponder(_:)), to: nil, from: nil, for: nil)
// The following 'defer' statement executes after the return
// While I could use a weak ref and eliminate this, I prefer a
// hard ref which I explicitly clear as it's better for race conditions
defer {
_foundFirstResponder = nil
}
return _foundFirstResponder
}
@objc func storeFirstResponder(_ sender: AnyObject) {
_foundFirstResponder = self
}
}
Затем я могу подать в отставку первого респондента, если таковой имеется, выполнив это ...
return UIResponder.first?.resignFirstResponder()
Но теперь я тоже могу это сделать ...
if let firstResponderTextField = UIResponder?.first as? UITextField {
// bla
}