J'ai soumis mon application il y a un peu plus d'une semaine et j'ai reçu l'e-mail de rejet redouté aujourd'hui. Il me dit que mon application ne peut pas être acceptée car j'utilise une API non publique; en particulier, il est dit,
L'API non publique incluse dans votre application est firstResponder.
Maintenant, l'appel d'API incriminé est en fait une solution que j'ai trouvée ici sur SO:
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
UIView *firstResponder = [keyWindow performSelector:@selector(firstResponder)];
Comment afficher le premier répondeur actuel à l'écran? Je cherche un moyen de ne pas rejeter mon application.
objective-c
cocoa-touch
first-responder
Justin Kredible
la source
la source
Réponses:
Dans l'une de mes applications, je souhaite souvent que le premier répondant démissionne si l'utilisateur appuie sur l'arrière-plan. À cet effet, j'ai écrit une catégorie sur UIView, que j'appelle sur UIWindow.
Ce qui suit est basé sur cela et devrait renvoyer le premier répondant.
iOS 7+
Rapide:
Exemple d'utilisation dans Swift:
la source
[self.view endEditing:YES]
?Si votre objectif ultime est simplement de démissionner du premier répondant, cela devrait fonctionner:
[self.view endEditing:YES]
la source
Une manière courante de manipuler le premier intervenant consiste à utiliser zéro actions ciblées. Il s'agit d'un moyen d'envoyer un message arbitraire à la chaîne de répondeurs (en commençant par le premier répondant) et de continuer le long de la chaîne jusqu'à ce que quelqu'un réponde au message (a mis en œuvre une méthode correspondant au sélecteur).
Dans le cas de la fermeture du clavier, c'est le moyen le plus efficace qui fonctionnera quelle que soit la fenêtre ou la vue qui est le premier intervenant:
Cela devrait être plus efficace que même
[self.view.window endEditing:YES]
.(Merci à BigZaphod de m'avoir rappelé le concept)
la source
Voici une catégorie qui vous permet de trouver rapidement le premier répondant en appelant
[UIResponder currentFirstResponder]
. Ajoutez simplement les deux fichiers suivants à votre projet:UIResponder + FirstResponder.h
UIResponder + FirstResponder.m
L'astuce ici est que l'envoi d'une action à nil l'envoie au premier répondant.
(J'ai initialement publié cette réponse ici: https://stackoverflow.com/a/14135456/322427 )
la source
Voici une extension implémentée dans Swift basée sur la meilleure réponse de Jakob Egger:
Swift 4
la source
current
place defirst
?Ce n'est pas joli, mais la façon dont je démissionne du premier répondeur quand je ne sais pas ce qu'est le répondeur:
Créez un UITextField, soit dans IB, soit par programme. Rendez-le caché. Associez-le à votre code si vous l'avez fait dans IB.
Ensuite, lorsque vous souhaitez fermer le clavier, vous basculez le répondeur vers le champ de texte invisible et vous le résignez immédiatement:
la source
Pour une version Swift 3 et 4 de la réponse de Nevyn :
la source
Voici une solution qui signale le premier répondant correct (de nombreuses autres solutions ne signalent pas un
UIViewController
comme premier répondant, par exemple), ne nécessite pas de bouclage sur la hiérarchie des vues et n'utilise pas d'API privées.Il exploite la méthode sendAction: d' Apple vers: from: forEvent:, qui sait déjà comment accéder au premier répondant.
Nous avons juste besoin de le modifier de 2 manières:
UIResponder
afin qu'il puisse exécuter notre propre code sur le premier répondant.UIEvent
afin de renvoyer le premier répondant.Voici le code:
la source
Le premier répondant peut être n'importe quelle instance de la classe UIResponder, il existe donc d'autres classes qui pourraient être le premier répondant malgré les UIViews. Par exemple,
UIViewController
pourrait également être le premier répondant.Dans cet aperçu, vous trouverez un moyen récursif d'obtenir le premier répondeur en parcourant la hiérarchie des contrôleurs à partir du rootViewController des fenêtres de l'application.
Vous pouvez alors récupérer le premier répondant en faisant
Cependant, si le premier répondeur n'est pas une sous-classe de UIView ou UIViewController, cette approche échouera.
Pour résoudre ce problème, nous pouvons faire une approche différente en créant une catégorie
UIResponder
et en effectuant un tour de magie pour pouvoir créer un tableau de toutes les instances vivantes de cette classe. Ensuite, pour obtenir le premier répondant, nous pouvons simplement itérer et demander à chaque objet si-isFirstResponder
.Cette approche peut être trouvée implémentée dans cet autre sens .
J'espère que ça aide.
la source
En utilisant Swift et avec un objet spécifique
UIView
, cela pourrait aider:Placez-le simplement dans votre
UIViewController
et utilisez-le comme ceci:Notez que le résultat est une valeur facultative , il sera donc nul si aucun firstResponser n'a été trouvé dans les sous-vues vues données.
la source
Répétez les vues qui pourraient être le premier répondant et utilisez
- (BOOL)isFirstResponder
pour déterminer si elles le sont actuellement.la source
Peter Steinberger vient de tweeter à propos de la notification privée
UIWindowFirstResponderDidChangeNotification
, que vous pouvez observer si vous souhaitez regarder le premier changement de répondeur.la source
Si vous avez juste besoin de tuer le clavier lorsque l'utilisateur appuie sur une zone d'arrière-plan, pourquoi ne pas ajouter un identificateur de geste et l'utiliser pour envoyer le
[[self view] endEditing:YES]
message?vous pouvez ajouter le reconnaisseur de gestes Tap dans le fichier xib ou storyboard et le connecter à une action,
ressemble à quelque chose comme ça, puis terminé
la source
Juste le cas ici est la version Swift de l'approche impressionnante de Jakob Egger:
la source
Voici ce que j'ai fait pour trouver ce que UITextField est le premier répondeur lorsque l'utilisateur clique sur Enregistrer / Annuler dans un ModalViewController:
la source
C'est ce que j'ai dans ma catégorie UIViewController. Utile pour de nombreuses choses, notamment pour obtenir le premier répondant. Les blocs sont super!
la source
Avec une catégorie activée
UIResponder
, il est possible de demander légalement à l'UIApplication
objet de vous dire qui est le premier répondant.Regarde ça:
Existe-t-il un moyen de demander à une vue iOS lequel de ses enfants a le statut de premier répondant?
la source
Vous pouvez choisir l'
UIView
extension suivante pour l'obtenir (crédit de Daniel) :la source
Vous pouvez également essayer comme ceci:
Je ne l'ai pas essayé mais cela semble une bonne solution
la source
La solution de romeo https://stackoverflow.com/a/2799675/661022 est cool, mais j'ai remarqué que le code a besoin d'une boucle de plus. Je travaillais avec tableViewController. J'ai édité le script puis j'ai vérifié. Tout fonctionnait parfaitement.
J'ai recommandé d'essayer ceci:
la source
if ([textField isKindOfClass:[UITextField class]])
, permettant l'utilisation d'uitextview, et retourner le premier répondant.C'est un bon candidat pour la récursivité! Pas besoin d'ajouter une catégorie à UIView.
Utilisation (depuis votre contrôleur de vue):
Code:
la source
vous pouvez appeler une API privée comme celle-ci, Apple ignore:
la source
Version rapide de la réponse de @ thomas-müller
la source
J'ai une approche légèrement différente de la plupart ici. Plutôt que de parcourir la collection de vues à la recherche de celle qui a été
isFirstResponder
définie, j'envoie également un message ànil
, mais je stocke le récepteur (le cas échéant), puis je renvoie cette valeur afin que l'appelant obtienne l'instance réelle (à nouveau, le cas échéant) .Je peux ensuite démissionner du premier intervenant, le cas échéant, en procédant ainsi ...
Mais je peux maintenant aussi faire ça ...
la source
Je voudrais partager avec vous mon implémentation pour trouver le premier répondant partout dans UIView. J'espère que cela aide et désolé pour mon anglais. Merci
la source
Code ci-dessous fonctionne.
la source
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 desUIViewController
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é deUIResponder
: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 aview
à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:
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 comprisUIWindow
.Et enfin, nous pouvons construire ceci:
Ainsi, lorsque vous souhaitez récupérer le premier répondant, vous pouvez appeler:
la source
Le moyen le plus simple de trouver le premier répondant:
L'étape suivante:
Utilisation: obtenez simplement
UIResponder.actualFirst
pour vos propres besoins.la source