Mise à jour: j'avais tort. Vous pouvez en effet utiliser UIApplication.shared.sendAction(_:to:from:for:)
pour appeler le premier répondant démontré dans ce lien: http://stackoverflow.com/a/14135456/746890 .
La plupart des réponses ici ne peuvent pas vraiment trouver le premier répondant actuel s'il n'est pas dans la hiérarchie des vues. Par exemple, AppDelegate
ou des UIViewController
sous - classes.
Il existe un moyen de vous garantir de le trouver même si le premier objet répondeur n'est pas a UIView
.
Permet d'abord d'en implémenter une version inversée, en utilisant la next
propriété de UIResponder
:
extension UIResponder {
var nextFirstResponder: UIResponder? {
return isFirstResponder ? self : next?.nextFirstResponder
}
}
Avec cette propriété calculée, nous pouvons trouver le premier répondant actuel de bas en haut, même s'il ne l'est pas UIView
. Par exemple, de a view
àUIViewController
qui le gère, si le contrôleur de vue est le premier répondant.
Cependant, nous avons toujours besoin d'une résolution descendante, une seule var
pour obtenir le premier répondeur actuel.
Tout d'abord avec la hiérarchie des vues:
extension UIView {
var previousFirstResponder: UIResponder? {
return nextFirstResponder ?? subviews.compactMap { $0.previousFirstResponder }.first
}
}
Cela recherchera le premier répondant à l'envers, et s'il ne le trouve pas, il dira à ses sous-vues de faire la même chose (parce que ses sous-vues ne next
sont pas nécessairement elles-mêmes). Avec cela, nous pouvons le trouver de n'importe quel point de vue, y compris UIWindow
.
Et enfin, nous pouvons construire ceci:
extension UIResponder {
static var first: UIResponder? {
return UIApplication.shared.windows.compactMap({ $0.previousFirstResponder }).first
}
}
Ainsi, lorsque vous souhaitez récupérer le premier répondant, vous pouvez appeler:
let firstResponder = UIResponder.first