Je me demande comment faire disparaître le clavier lorsque l'utilisateur touche en dehors d'un UITextField
.
Je me demande comment faire disparaître le clavier lorsque l'utilisateur touche en dehors d'un UITextField
.
Réponses:
Vous devrez ajouter un UITapGestureRecogniser
et l'attribuer à la vue, puis appeler démissionner premier intervenant sur le UITextField
sélecteur on it.
Le code:
In viewDidLoad
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
Dans le cas du clavier ignoré:
-(void)dismissKeyboard
{
[aTextField resignFirstResponder];
}
(Où aTextField
est le champ de texte qui est responsable du clavier)
La version Swift 3 ressemble à ça
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard (_:)))
self.view.addGestureRecognizer(tapGesture)
Pour ignorer le clavier
@objc func dismissKeyboard (_ sender: UITapGestureRecognizer) {
aTextField.resignFirstResponder()
}
[aTextField resignFirstResponder]
ne serait [self.view endEditing:YES];
pas besoin d'une référence au champ de texte et fonctionnera pour plusieurs champs de texte
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self.view action:@selector(endEditing:)]];
[tap setCancelsTouchesInView:NO];
selon la réponse de @qiaoyi; J'ai eu un problème avec une table ne répondant pas aux sélections de lignes. 5 ans plus tard, j'espère que cela aide quelqu'un d'autre.
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
J'ai mélangé quelques réponses.
Utilisez un ivar qui s'initialise pendant viewDidLoad:
UIGestureRecognizer *tapper;
- (void)viewDidLoad
{
[super viewDidLoad];
tapper = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(handleSingleTap:)];
tapper.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:tapper];
}
Ignorer ce qui est en cours d'édition:
- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
[self.view endEditing:YES];
}
Vérifiez ceci, ce serait le moyen le plus simple de le faire,
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.view endEditing:YES];// this will do the trick
}
Ou
Cette bibliothèque gérera notamment le défilement automatique de la barre de défilement, appuyez sur l'espace pour masquer le clavier, etc.
Je constate que certaines personnes ont des problèmes avec la UITapGestureRecognizer
méthode. Le moyen le plus simple que j'ai accompli cette fonctionnalité tout en laissant intact le comportement de tapotement de mon bouton existant est d'ajouter une seule ligne à la réponse de @ Jensen2k:
[tap setCancelsTouchesInView:NO];
Cela a permis à mes boutons existants de fonctionner sans utiliser la méthode de @Dmitry Sitnikov.
Lisez à ce sujet property
ici (recherchez CancelsTouchesInView
): UIGestureRecognizer Class Reference
Je ne sais pas comment cela fonctionnerait avec les barres de défilement, car je vois que certains avaient des problèmes, mais j'espère que quelqu'un d'autre pourrait rencontrer le même scénario que moi.
UIImageView
, ajoutez [imageView setUserInteractionEnabled:NO];
et vous "cliquez dessus", ce qui fait que cette méthode fonctionne.
Il est préférable de créer UIView
une instance de UIControl
(dans le générateur d'interface), puis de connecter leur TouchUpInside
événement à la dismissKeyboard
méthode. Cette IBAction
méthode ressemblera à:
- (IBAction)dismissKeyboard:(id)sender {
[aTextBox resignFirstResponder];
}
UITapGestureRecognizer
interféré en tapant sur les boutons à l'intérieur de la vue). touchesEnded
n'a pas fonctionné car il y a eu un UIScrollView
problème avec la chaîne de répondeurs.)
Swift 4
Configurez votre UIViewController
avec cette méthode d'extension une fois par exemple dans viewDidLoad
:
override func viewDidLoad() {
super.viewDidLoad()
self.setupHideKeyboardOnTap()
}
et le clavier sera ignoré même en appuyant sur NavigationBar
.
import UIKit
extension UIViewController {
/// Call this once to dismiss open keyboards by tapping anywhere in the view controller
func setupHideKeyboardOnTap() {
self.view.addGestureRecognizer(self.endEditingRecognizer())
self.navigationController?.navigationBar.addGestureRecognizer(self.endEditingRecognizer())
}
/// Dismisses the keyboard from self.view
private func endEditingRecognizer() -> UIGestureRecognizer {
let tap = UITapGestureRecognizer(target: self.view, action: #selector(self.view.endEditing(_:)))
tap.cancelsTouchesInView = false
return tap
}
}
Version Swift, cela fonctionne en combinaison avec d'autres éléments (comme l'un UIButton
ou l'autre UITextField
):
override func viewDidLoad() {
super.viewDidLoad()
let tapper = UITapGestureRecognizer(target: self, action:#selector(endEditing))
tapper.cancelsTouchesInView = false
view.addGestureRecognizer(tapper)
}
self
plutôt queself.view
canclesTouchesInView
est une propriété pratique à utiliser. Merci.
c#
. FYI Ce point-virgule est autorisé par la syntaxe, ce n'est tout simplement pas nécessaire.
Que diriez-vous de ceci: je sais que c'est un vieux poste. Cela pourrait aider quelqu'un :)
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSArray *subviews = [self.view subviews];
for (id objects in subviews) {
if ([objects isKindOfClass:[UITextField class]]) {
UITextField *theTextField = objects;
if ([objects isFirstResponder]) {
[theTextField resignFirstResponder];
}
}
}
}
C'est une bonne solution générique:
Objectif c:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
Rapide:
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.view.endEditing(true)
}
Basé sur la solution @icodebuster: https://stackoverflow.com/a/18756253/417652
Swift 4 oneliner
view.addGestureRecognizer(UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))))
Je pense que la façon la plus simple (et la meilleure) de le faire est de sous-classer votre vue globale et d'utiliser la hitTest:withEvent
méthode pour écouter n'importe quelle touche. Les touches du clavier ne sont pas enregistrées, donc hitTest: withEvent n'est appelé que lorsque vous touchez / défiler / glissez / pincez ... ailleurs, puis appelez[self endEditing:YES]
.
C'est mieux que d'utiliser touchesBegan
cartouchesBegan
ne sont pas appelés si vous cliquez sur un bouton en haut de la vue. C'est mieux que celui UITapGestureRecognizer
qui ne peut pas reconnaître un geste de défilement par exemple. C'est aussi mieux que d'utiliser un écran sombre car dans une interface utilisateur complexe et dynamique, vous ne pouvez pas mettre d'écran tamisé partout. De plus, il ne bloque pas les autres actions, vous n'avez pas besoin d'appuyer deux fois pour sélectionner un bouton à l'extérieur (comme dans le cas d'unUIPopover
).
En outre, c'est mieux que d'appeler [textField resignFirstResponder]
, car vous pouvez avoir de nombreux champs de texte à l'écran, donc cela fonctionne pour chacun d'eux.
Ce doit être le moyen le plus simple de cacher votre clavier en touchant l'extérieur:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
(à partir de Comment fermer le clavier lorsque l'utilisateur touche une autre zone en dehors du champ de texte? )
Si la vue est intégrée dans un, UIScrollView
vous pouvez utiliser ce qui suit:
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
Le premier animera le clavier hors écran lorsque la vue de la table défile et le dernier masquera le clavier comme l'application Messages standard.
Notez que ceux-ci sont disponibles sur iOS 7.0 ou supérieur.
Vous pouvez le faire en utilisant le Storyboard dans XCode 6 et supérieur:
Ajoutez ceci au fichier d'en-tête de la classe utilisée par votre ViewController:
@interface TimeDelayViewController : UIViewController <UITextFieldDelegate>
- (IBAction)dissmissKeyboardOnTap:(id)sender;
@end
Ajoutez ensuite ceci au fichier d'implémentation du même ViewController:
- (IBAction)dissmissKeyboardOnTap:(id)sender{
[[self view]endEditing:YES];
}
Ce sera maintenant l'une des «Actions reçues» pour votre scène de storyboard (ie ViewController):
Vous devez maintenant connecter cette action au geste de l'utilisateur de toucher le clavier.
Important - Vous devez convertir la «UIView» contenue dans votre storyboard en UIControl , afin qu'il puisse recevoir des événements. Sélectionnez la vue dans votre hiérarchie View Controller Scene:
... et changez de classe:
Faites maintenant glisser le petit cercle à côté de «l'action reçue» pour votre scène, sur une partie «vide» de votre scène (en fait, vous faites glisser «l'action reçue» vers l'UIControl). Vous verrez une sélection d'événements auxquels vous pouvez connecter votre action:
Sélectionnez l'option «retouche à l'intérieur». Vous avez maintenant accroché l'IBAction que vous avez créée à une action utilisateur consistant à toucher le clavier. Lorsque l'utilisateur tape sur le clavier, il est désormais masqué.
(REMARQUE: pour accrocher l'action à l'événement, vous pouvez également faire glisser l'action reçue directement sur l'UIControl dans votre hiérarchie View Controllers. Elle est affichée en tant que «Contrôle» dans la hiérarchie.)
Si je vous comprends bien, vous voulez démissionner en tapant sur le clavier de l'extérieur, textfield
mais vous n'avez pas de référence textfield
.
Essaye ça;
reftextField
Maintenant, textFieldDidBeginEditing
définissez le champ de texte référencé sur
- (void) textFieldDidBeginEditing:(UITextField *)textField{
reftextField = textField;
}
Maintenant, vous pouvez l'utiliser avec plaisir sur n'importe quelle horloge de bouton (ajouter un bouton transparent au début de l'édition est recommandé)
- (void)dismissKeyboard {
[reftextField resignFirstResponder];
}
Ou pour démissionner du bouton terminé, essayez ceci.
//for resigning on done button
- (BOOL) textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
Juste pour ajouter à la liste ici ma version de la façon de rejeter un clavier sur une touche extérieure.
viewDidLoad:
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleTap];
Nulle part:
-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
[textFieldName resignFirstResponder];
puts("Dismissed the keyboard");
}
Beaucoup de bonnes réponses ici sur l'utilisation de - UITapGestureRecognizer
tous les UITextField
boutons effacer (X). La solution est de supprimer le reconnaisseur de gestes via son délégué:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
BOOL touchViewIsButton = [touch.view isKindOfClass:[UIButton class]];
BOOL touchSuperviewIsTextField = [[touch.view superview] isKindOfClass:[UITextField class]];
return !(touchViewIsButton && touchSuperviewIsTextField);
}
Ce n'est pas la solution la plus robuste mais elle fonctionne pour moi.
return !touchViewIsButton
. Je suppose que tous les autres boutons qui doivent fermer le clavier devraient le faire dans leurs actions. De plus, TouchUpInside peut ne pas être appelé lorsque la disposition change lors de la fermeture du clavier.
Vous pouvez créer une catégorie pour l'UiView et remplacer le meathod touchesBegan comme suit.
Cela fonctionne bien pour moi et c'est une solution centralisée pour ce problème.
#import "UIView+Keyboard.h"
@implementation UIView(Keyboard)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.window endEditing:true];
[super touchesBegan:touches withEvent:event];
}
@end
Version rapide de la réponse de @ Jensen2k:
let gestureRecognizer : UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: "dismissKeyboard")
self.view.addGestureRecognizer(gestureRecognizer)
func dismissKeyboard() {
aTextField.resignFirstResponder()
}
Bon mot
self.view.addTapGesture(UITapGestureRecognizer.init(target: self, action: "endEditing:"))
J'ai utilisé l'exemple de Barry pour mon nouveau développement. Cela a très bien fonctionné! mais j'ai dû inclure un léger changement, nécessaire pour ignorer le clavier uniquement pour le champ de texte en cours d'édition.
J'ai donc ajouté à l'exemple de Barry ce qui suit:
- (void) textFieldDidBeginEditing:(UITextField *)textField
{
_textBeingEdited = textField;
}
-(void) textFieldDidEndEditing:(UITextField *)textField
{
_textBeingEdited = nil;
}
De plus, j'ai changé la méthode hideKeyboard comme suit:
- (IBAction)hideKeyboard:(id)sender
{
// Just call resignFirstResponder on all UITextFields and UITextViews in this VC
// Why? Because it works and checking which one was last active gets messy.
//UITextField * tf = (UITextField *) sender;
[_textBeingEdited resignFirstResponder];
}
L'un des moyens les plus simples et les plus courts consiste à ajouter ce code à votre viewDidLoad
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc]
initWithTarget:self.view
action:@selector(endEditing:)]];
J'ai essayé plusieurs des réponses ici et n'ai pas eu de chance. Mon identificateur de geste de prise de contact m'empêchait toujours UIButtons
de répondre lorsqu'il était appuyé, même lorsque je réglaiscancelsTouchesInView
propriété de l’identificateur de geste sur NON.
C'est ce qui a finalement résolu le problème:
Ayez un ivar:
UITapGestureRecognizer *_keyboardDismissGestureRecognizer;
Lorsqu'un champ de texte commence à être modifié, définissez la reconnaissance des gestes:
- (void) textFieldDidBeginEditing:(UITextField *)textField
{
if(_keyboardDismissGestureRecognizer == nil)
{
_keyboardDismissGestureRecognizer = [[[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissKeyboard)] autorelease];
_keyboardDismissGestureRecognizer.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:_keyboardDismissGestureRecognizer];
}
}
Ensuite, l'astuce consiste à configurer la dismissKeyboard
méthode:
- (void) dismissKeyboard
{
[self performSelector:@selector(dismissKeyboardSelector) withObject:nil afterDelay:0.01];
}
- (void) dismissKeyboardSelector
{
[self.view endEditing:YES];
[self.view removeGestureRecognizer:_keyboardDismissGestureRecognizer];
_keyboardDismissGestureRecognizer = nil;
}
Je suppose qu'il y a juste quelque chose à obtenir l' dismissKeyboardSelector
exécution hors de la pile d'exécution de manipulation tactile ...
Envoyer un message resignFirstResponder
au fichier texte qui l'a mis là. Veuillez consulter cet article pour plus d'informations.
Dans cet exemple, aTextField est le seul UITextField .... S'il y en a d'autres ou UITextViews, il y a un tout petit peu plus à faire.
// YourViewController.h
// ...
@interface YourViewController : UIViewController /* some subclass of UIViewController */ <UITextFieldDelegate> // <-- add this protocol
// ...
@end
// YourViewController.m
@interface YourViewController ()
@property (nonatomic, strong, readonly) UITapGestureRecognizer *singleTapRecognizer;
@end
// ...
@implementation
@synthesize singleTapRecognizer = _singleTapRecognizer;
// ...
- (void)viewDidLoad
{
[super viewDidLoad];
// your other init code here
[self.view addGestureRecognizer:self.singleTapRecognizer];
{
- (UITapGestureRecognizer *)singleTapRecognizer
{
if (nil == _singleTapRecognizer) {
_singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapToDismissKeyboard:)];
_singleTapRecognizer.cancelsTouchesInView = NO; // absolutely required, otherwise "tap" eats events.
}
return _singleTapRecognizer;
}
// Something inside this VC's view was tapped (except the navbar/toolbar)
- (void)singleTapToDismissKeyboard:(UITapGestureRecognizer *)sender
{
NSLog(@"singleTap");
[self hideKeyboard:sender];
}
// When the "Return" key is pressed on the on-screen keyboard, hide the keyboard.
// for protocol UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField*)textField
{
NSLog(@"Return pressed");
[self hideKeyboard:textField];
return YES;
}
- (IBAction)hideKeyboard:(id)sender
{
// Just call resignFirstResponder on all UITextFields and UITextViews in this VC
// Why? Because it works and checking which one was last active gets messy.
[aTextField resignFirstResponder];
NSLog(@"keyboard hidden");
}
- (void)viewDidLoad
{
[super viewDidLoad];
UITapGestureRecognizer *singleTapGestureRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(handleSingleTap:)];
[singleTapGestureRecognizer setNumberOfTapsRequired:1];
[singleTapGestureRecognizer requireGestureRecognizerToFail:singleTapGestureRecognizer];
[self.view addGestureRecognizer:singleTapGestureRecognizer];
}
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
[self.view endEditing:YES];
[textField resignFirstResponder];
[scrollView setContentOffset:CGPointMake(0, -40) animated:YES];
}
Ajoutez ce code dans votre fichier ViewController.m :
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
Dans ce cas, il peut être utilisé ScrollView et ajouté à TextField
ScrollView et je veux appuyer sur ScrollView
et Afficher, puis ignorer le clavier. J'ai essayé de créer un exemple de code au cas où. Comme ça,
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.tap(_:)))
view.addGestureRecognizer(tapGesture)
// Do any additional setup after loading the view, typically from a nib.
}
func tap(gesture: UITapGestureRecognizer) {
textField.resignFirstResponder()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Votre Storyboard Regardez ça comme.
Vous pouvez utiliser la méthode UITapGestureRecongnizer pour fermer le clavier en cliquant en dehors d'UITextField. En utilisant cette méthode chaque fois que l'utilisateur clique en dehors de UITextField, le clavier est ignoré. Voici l'extrait de code pour l'utiliser.
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissk)];
[self.view addGestureRecognizer:tap];
//Method
- (void) dismissk
{
[abctextfield resignFirstResponder];
[deftextfield resignFirstResponder];
}