Je me demande comment faire disparaître le clavier lorsque l'utilisateur touche en dehors d'un UITextField
.
Vous devez ajouter un UITapGestureRecogniser
et l'affecter à la vue, puis appeler le premier répondant démissionnaire sur le UITextField
de son sélecteur.
Le code:
dans viewDidLoad
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
Dans licenciement :)
-(void)dismissKeyboard
{
[aTextField resignFirstResponder];
}
(Où aTextField
est le champ de texte responsable du clavier)
Swift la version ressemble à ça
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard (_:)))
self.view.addGestureRecognizer(tapGesture)
Pour licenciement
func dismissKeyboard (_ sender: UITapGestureRecognizer) {
aTextField.resignFirstResponder()
}
J'ai écrasé quelques réponses.
Utilisez un ivar initialisé 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 train d'être édité:
- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
[self.view endEditing:YES];
}
Cochez 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, la touche Tap pour masquer le clavier, etc.
Je vois que certaines personnes ont des problèmes avec la méthode UITapGestureRecognizer
. Le moyen le plus simple d’effectuer cette fonctionnalité tout en conservant intact le comportement de mon bouton actuel consiste à ajouter une seule ligne à la réponse de @ Jensen2k:
[tap setCancelsTouchesInView:NO];
Cela a permis à mes boutons existants de continuer à fonctionner sans utiliser la méthode de @Dmitry Sitnikov.
Lisez à ce sujet property
ici (recherchez CancelsTouchesInView
): Référence de la classe UIGestureRecognizer
Je ne suis pas sûr de savoir 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 rencontrera le même scénario que moi.
Il est préférable de faire de votre UIView
une instance de UIControl
(dans le générateur d'interface), puis de connecter leur événement TouchUpInside
à la méthode dismissKeyboard
. Cette méthode IBAction
ressemblera à ceci:
- (IBAction)dismissKeyboard:(id)sender {
[aTextBox resignFirstResponder];
}
Version rapide, cela fonctionne en combinaison avec d'autres éléments (comme un UIButton
ou un autre UITextField
):
override func viewDidLoad() {
super.viewDidLoad()
let tapper = UITapGestureRecognizer(target: self, action:#selector(endEditing))
tapper.cancelsTouchesInView = false
view.addGestureRecognizer(tapper)
}
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 tapant sur la touche 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
}
}
Que diriez-vous de cela: je sais que c'est un ancien post. 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
Je pense que le moyen le plus simple (et le meilleur) de procéder consiste à sous-classer votre vue globale et à utiliser la méthode hitTest:withEvent
pour écouter tout contact. Les touches du clavier n'étant pas enregistrées, hitTest: withEvent n'est appelé que lorsque vous touchez/défilez/balayez/pincez ... ailleurs, puis appelez [self endEditing:YES]
.
C'est mieux que d'utiliser touchesBegan
parce que touchesBegan
ne sont pas appelés si vous cliquez sur un bouton en haut de la vue. C'est mieux que UITapGestureRecognizer
qui ne reconnaît pas un geste de défilement par exemple. C'est également mieux que d'utiliser un écran sombre, car dans une interface utilisateur complexe et dynamique, vous ne pouvez pas placer l'écran sombre partout. De plus, il ne bloque pas d'autres actions, vous n'avez pas besoin d'appuyer deux fois pour sélectionner un bouton extérieur (comme dans le cas d'un UIPopover
).
En outre, il vaut mieux appeler [textField resignFirstResponder]
, car vous pouvez avoir plusieurs champs de texte à l'écran, donc cela fonctionne pour tous.
Swift 4 oneliner
view.addGestureRecognizer(UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))))
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 désormais l'une des 'Actions reçues' pour votre scène de scénario (c'est-à-dire ViewController):
Vous devez maintenant associer cette action au geste de l'utilisateur consistant à toucher le clavier.
Important - Vous devez convertir le 'UIView' contenu dans votre storyboard en UIControl afin qu'il puisse recevoir des événements. Sélectionnez la vue dans votre hiérarchie de scènes de contrôleur de vue:
... et change de classe:
À présent, faites glisser le cercle situé à côté de "l'action reçue" pour votre scène, sur une partie "vide" de votre scène (vous faites en fait glisser l'action "reçue" vers UIControl). Une sélection d'événements que vous pouvez associer à votre action vous sera présentée:
Sélectionnez l'option "Retouche à l'intérieur". Vous avez maintenant associé l'IBAction que vous avez créée à une action utilisateur consistant à toucher le clavier. Lorsque l'utilisateur appuie sur le clavier, celui-ci est maintenant masqué.
(REMARQUE: pour associer l'action à l'événement, vous pouvez également faire glisser l'action reçue directement sur UIControl dans la hiérarchie de vos contrôleurs de vue. Il est affiché sous la forme "Control" dans la hiérarchie.)
Ce doit être le moyen le plus simple de masquer votre clavier en touchant à l'extérieur:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
(de Comment supprimer un clavier lorsque l'utilisateur appuie sur une autre zone en dehors de textfield? )
Si la vue est incorporée dans un UIScrollView
, vous pouvez utiliser les éléments suivants:
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
Le premier animera l’écran de désactivation du clavier lors du défilement de la vue du tableau et le second masquera le clavier comme l’application stock Messages.
Notez que ceux-ci sont disponibles sur iOS 7.0 ou une version ultérieure.
Si je comprends bien, vous voulez quitter le clavier en tapant sur le côté extérieur de textfield
mais vous n'avez pas de référence de votre textfield
.
Essaye ça;
reftextField
Maintenant, dans textFieldDidBeginEditing
, définissez le champ de texte référencé sur
- (void) textFieldDidBeginEditing:(UITextField *)textField{
reftextField = textField;
}
Maintenant, vous pouvez utiliser avec bonheur n'importe quelle horloge à boutons (ajouter un bouton transparent pour commencer l'édition recommandée)
- (void)dismissKeyboard {
[reftextField resignFirstResponder];
}
Ou pour le bouton de démission fait, essayez ceci.
//for resigning on done button
- (BOOL) textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
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:"))
Juste pour ajouter à la liste ici ma version de la façon de supprimer un clavier sans contact.
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
-- toutes qui cassent le bouton clear (X) de UITextField
. La solution consiste à supprimer la reconnaissance de geste 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 cela fonctionne pour moi.
Vous pouvez créer une catégorie pour UiView et remplacer le meathod de toucheBegan comme suit.
Cela fonctionne très 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
L’un des moyens les plus simples et les plus simples consiste à ajouter ce code à votre viewDidLoad
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc]
initWithTarget:self.view
action:@selector(endEditing:)]];
J'ai essayé beaucoup de réponses ici et je n'ai pas eu de chance. Mon outil de reconnaissance des gestes entraînait toujours mon UIButtons
à ne pas répondre lorsqu'il était tapé, même lorsque je définissais la propriété cancelsTouchesInView
du dispositif de reconnaissance des gestes sur NO.
C'est ce qui a finalement résolu le problème:
Avoir un ivar:
UITapGestureRecognizer *_keyboardDismissGestureRecognizer;
Lorsqu'un texte commence à être modifié, définissez la reconnaissance de geste:
- (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 méthode dismissKeyboard
:
- (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 simplement quelque chose à faire pour obtenir l'exécution dismissKeyboardSelector
de la pile d'exécution du traitement tactile ...
J'ai utilisé l'exemple de Barry pour mon nouveau développement. Cela a très bien fonctionné! mais je devais inclure un léger changement, obligé de fermer le clavier uniquement pour le champ de texte en cours d'édition.
Donc, j'ai 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];
}
Dans cet exemple, aTextField est le seul UITextField ... S'il y en a d'autres ou UITextViews, il reste un 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");
}
Dans ce cas, il peut y avoir utilisation ScrollView et ajouté à TextField
dans ScrollView et je veux Tapotez sur le ScrollView
et cliquez sur Afficher Rejeter 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 si.
Définir le délégué des champs de texte en vue chargé:
override func viewDidLoad()
{
super.viewDidLoad()
self.userText.delegate = self
}
Ajouter cette fonction:
func textFieldShouldReturn(userText: UITextField!) -> Bool
{
userText.resignFirstResponder()
return true;
}
Ajoutez ce code dans votre fichier ViewController.m:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
- (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];
}
Vous pouvez utiliser la méthode UITapGestureRecongnizer pour supprimer le clavier en cliquant en dehors de UITextField. En utilisant cette méthode chaque fois que l'utilisateur clique en dehors de UITextField, le clavier est ignoré. Ci-dessous 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];
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first{
view.endEditing(true)
}
}
Envoyez le message resignFirstResponder
au champ de texte qui l’a indiqué. S'il vous plaît voir cet article pour plus d'informations.
Pour ceux qui luttent avec cela dans Swift. C'est la réponse acceptée par Jensen2k mais dans Swift.
Swift 2.
override func viewDidLoad() {
//.....
let viewTapGestureRec = UITapGestureRecognizer(target: self, action: #selector(handleViewTap(_:)))
//this line is important
viewTapGestureRec.cancelsTouchesInView = false
self.view.addGestureRecognizer(viewTapGestureRec)
//.....
}
func handleViewTap(recognizer: UIGestureRecognizer) {
myTextField.resignFirstResponder()
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
super.view.endEditing(true)
super.touchesBegan(touches, withEvent: event)
}
Dans viewDidLoad Swift 4.2 Le code comme celui-ci
let viewTap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action:#selector(dismissKeyboard))
view.addGestureRecognizer(viewTap)
@objc func dismissKeyboard() {
view.endEditing(true)
}
utilisez simplement ce code dans votre fichier .m, il résiliera le champ de texte lorsque l’utilisateur tapera en dehors du champ de texte.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[textfield resignFirstResponder];
}
Je devais donc simplement résoudre ce problème et aucune des réponses précédentes ne fonctionnait pour moi hors de la boîte. Ma situation: a UISearchBar
, plus un certain nombre de commandes à l'écran. Je veux qu'un tapotement en dehors de la barre de recherche ferme le clavier, mais not se propage à l'un des autres contrôles. Lorsque le clavier est masqué, je souhaite que toutes les commandes fonctionnent.
Ce que j'ai fait:
1) Implémentez un gestionnaire tactile personnalisé dans mon contrôleur de vue.
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
if searchBar.isFirstResponder()
{
// This causes the first responder, whoever it is, to resign first responder, and hide the keyboard.
// We also "eat" the touch here and not allow it to propagate further.
view.endEditing(true)
}
else
{
// OK to propagate the touch
super.touchesBegan(touches, withEvent: event)
}
}
2) Ajout de deux méthodes de délégué (les miennes sont pour le UISearchBar, mais il en existe des similaires pour UITextField). controlContainerView
dans le code ci-dessous est un UIView qui a un tas de boutons. Rappelez-vous que le réglage de userInteractionEnabled
sur un superview désactive toutes ses sous-vues.
func searchBarTextDidBeginEditing(searchBar: UISearchBar)
{
controlContainerView.userInteractionEnabled = false
someButton.userInteractionEnabled = false
}
func searchBarTextDidEndEditing(searchBar: UISearchBar)
{
searchBar.resignFirstResponder()
// Done editing: enable the other controls again.
controlContainerView.userInteractionEnabled = false
someButton.userInteractionEnabled = false
}