Me pregunto cómo hacer que el teclado desaparezca cuando el usuario toca fuera de a UITextField
.
Me pregunto cómo hacer que el teclado desaparezca cuando el usuario toca fuera de a UITextField
.
Respuestas:
Tendrá que agregar un UITapGestureRecogniser
y asignarlo a la vista, y luego llamar a resignar primer respondedor UITextField
en su selector.
El código:
En vistaDidLoad
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
En despedir Teclado:
-(void)dismissKeyboard
{
[aTextField resignFirstResponder];
}
(¿Dónde aTextField
está el campo de texto responsable del teclado?)
La versión Swift 3 se ve así
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard (_:)))
self.view.addGestureRecognizer(tapGesture)
Para despedir Keyboard
@objc func dismissKeyboard (_ sender: UITapGestureRecognizer) {
aTextField.resignFirstResponder()
}
[aTextField resignFirstResponder]
lo que sería [self.view endEditing:YES];
, no necesita una referencia al campo de texto y funcionará para múltiples campos de texto
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self.view action:@selector(endEditing:)]];
[tap setCancelsTouchesInView:NO];
según la respuesta de @qiaoyi; Tuve un problema con una tabla que no responde a las selecciones de fila. 5 años después, espero que esto ayude a alguien más.
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
Apreté algunas respuestas.
Use un ivar que se inicializa durante viewDidLoad:
UIGestureRecognizer *tapper;
- (void)viewDidLoad
{
[super viewDidLoad];
tapper = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(handleSingleTap:)];
tapper.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:tapper];
}
Descarte lo que esté editando actualmente:
- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
[self.view endEditing:YES];
}
Mira esto, esta sería la forma más fácil de hacerlo,
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.view endEditing:YES];// this will do the trick
}
O
Esta biblioteca se encargará de incluir el desplazamiento automático de la barra de desplazamiento, tocar el espacio para ocultar el teclado, etc.
Veo que algunas personas tienen problemas para usar el UITapGestureRecognizer
método. La manera más fácil de lograr esta funcionalidad sin dejar intacto el comportamiento de toque de mi botón existente es agregar solo una línea a la respuesta de @ Jensen2k:
[tap setCancelsTouchesInView:NO];
Esto permitió que mis botones existentes siguieran funcionando sin usar el método de @Dmitry Sitnikov.
Lea sobre eso property
aquí (busque CancelsTouchesInView
): Referencia de clase de UIGestureRecognizer
No estoy seguro de cómo funcionaría con las barras de desplazamiento, ya que veo que algunos tenían problemas, pero espero que alguien más se encuentre con el mismo escenario que yo.
UIImageView
, agregue [imageView setUserInteractionEnabled:NO];
y haga clic en ella, lo que hace que este método funcione.
Es mejor hacer UIView
una instancia de UIControl
(en el generador de interfaces) y luego conectar su TouchUpInside
evento al dismissKeyboard
método. EstaIBAction
método se verá así:
- (IBAction)dismissKeyboard:(id)sender {
[aTextBox resignFirstResponder];
}
UITapGestureRecognizer
interferido con tocar botones dentro de la vista). touchesEnded
no funcionó porque había un problema UIScrollView
con la cadena de respuesta.)
Swift 4
Configure su UIViewController
con este método de extensión una vez, por ejemplo, en viewDidLoad
:
override func viewDidLoad() {
super.viewDidLoad()
self.setupHideKeyboardOnTap()
}
y el teclado se cerrará incluso tocando el botón 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
}
}
Versión rápida, esto funciona en combinación con otros elementos (como uno UIButton
u otro UITextField
):
override func viewDidLoad() {
super.viewDidLoad()
let tapper = UITapGestureRecognizer(target: self, action:#selector(endEditing))
tapper.cancelsTouchesInView = false
view.addGestureRecognizer(tapper)
}
self
más queself.view
canclesTouchesInView
Es una propiedad útil para usar. Gracias.
c#
. FYI Ese punto y coma tiene sintaxis permitida, simplemente no es necesario.
Qué tal esto: Sé que esta es una publicación antigua. Podría ayudar a alguien :)
- (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];
}
}
}
}
Esta es una buena solución genérica:
C objetivo:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
Rápido:
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.view.endEditing(true)
}
Basado en la solución @icodebuster: https://stackoverflow.com/a/18756253/417652
Swift 4 oneliner
view.addGestureRecognizer(UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))))
Creo que la forma más fácil (y mejor) de hacer esto es subclasificar su vista global y usar el hitTest:withEvent
método para escuchar cualquier toque. Los toques en el teclado no están registrados, así que hitTest: withEvent solo se llama cuando tocas / desplazas / deslizas / pellizcas ... en otro lugar, luego llamas [self endEditing:YES]
.
Esto es mejor que usar touchesBegan
porque touchesBegan
no se llama si hace clic en un botón en la parte superior de la vista. Es mejor UITapGestureRecognizer
que no reconocer un gesto de desplazamiento, por ejemplo. También es mejor que usar una pantalla tenue porque en una interfaz de usuario compleja y dinámica, no se puede poner la pantalla tenue en todas partes. Además, no bloquea otras acciones, no necesita tocar dos veces para seleccionar un botón en el exterior (como en el caso de a UIPopover
).
Además, es mejor que llamar [textField resignFirstResponder]
, ya que puede tener muchos campos de texto en la pantalla, por lo que esto funciona para todos ellos.
Esta debe ser la forma más fácil de ocultar su teclado tocando afuera:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
(de ¿Cómo descartar el teclado cuando el usuario toca otra área fuera del campo de texto? )
Si la vista está incrustada en absoluto UIScrollView
, puede usar lo siguiente:
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
El primero animará el teclado fuera de la pantalla cuando se desplaza la vista de la tabla y el segundo ocultará el teclado como la aplicación de Mensajes.
Tenga en cuenta que estos están disponibles en iOS 7.0 o superior.
Puede hacer esto usando el Storyboard en XCode 6 y superior:
Agregue esto al archivo de encabezado de la clase utilizada por su ViewController:
@interface TimeDelayViewController : UIViewController <UITextFieldDelegate>
- (IBAction)dissmissKeyboardOnTap:(id)sender;
@end
Luego agregue esto al archivo de implementación del mismo ViewController:
- (IBAction)dissmissKeyboardOnTap:(id)sender{
[[self view]endEditing:YES];
}
Esta será ahora una de las 'Acciones recibidas' para su escena del guión gráfico (es decir, ViewController):
Ahora debe conectar esta acción al gesto del usuario de tocar el teclado.
Importante: debe convertir el 'UIView' que está contenido en su guión gráfico a un UIControl , para que pueda recibir eventos. Seleccione la vista de su jerarquía de escena del controlador de vista:
... y cambia su clase:
Ahora arrastre desde el círculo pequeño al lado de la 'acción recibida' para su escena, a una parte 'vacía' de su escena (en realidad está arrastrando la 'Acción recibida' al UIControl). Se le mostrará una selección de eventos a los que puede conectar su acción para:
Seleccione la opción 'retocar dentro'. Ahora ha conectado la IBAction que creó a la acción del usuario de tocar el teclado. Cuando el usuario toca el teclado, ahora estará oculto.
(NOTA: Para enganchar la acción al evento, también puede arrastrar desde la acción recibida directamente al UIControl en la jerarquía de View Controllers. Se muestra como 'Control' en la jerarquía).
Si te entendí bien, quieres renunciar al teclado mientras tocas el lado textfield
pero no tienes referencia de tutextfield
.
Prueba esto;
reftextField
Ahora en textFieldDidBeginEditing
establecer campo de texto referenciado a
- (void) textFieldDidBeginEditing:(UITextField *)textField{
reftextField = textField;
}
Ahora puede usarlo felizmente en cualquier reloj de botón (se recomienda agregar un botón transparente al comenzar a editar)
- (void)dismissKeyboard {
[reftextField resignFirstResponder];
}
O para renunciar al botón hecho, intente esto.
//for resigning on done button
- (BOOL) textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
Solo para agregar a la lista aquí mi versión de cómo descartar un teclado en el toque externo.
viewDidLoad:
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleTap];
En cualquier sitio:
-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
[textFieldName resignFirstResponder];
puts("Dismissed the keyboard");
}
Un montón de excelentes respuestas aquí sobre el uso de UITapGestureRecognizer
--todos de los cuales se rompe UITextField
el botón claro (X). La solución es suprimir el reconocedor de gestos a través de su delegado:
- (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);
}
No es la solución más robusta, pero funciona para mí.
return !touchViewIsButton
. Supongo que cualquier otro botón que deba descartar el teclado debería hacerlo en sus acciones. Además, es posible que no se llame a TouchUpInside cuando el diseño cambia al cerrar el teclado.
Puede crear una categoría para UiView y anular los toques de inicio del método de la siguiente manera.
Me está funcionando bien y es una solución centralizada para este problema.
#import "UIView+Keyboard.h"
@implementation UIView(Keyboard)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.window endEditing:true];
[super touchesBegan:touches withEvent:event];
}
@end
Versión rápida de la respuesta de @ Jensen2k:
let gestureRecognizer : UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: "dismissKeyboard")
self.view.addGestureRecognizer(gestureRecognizer)
func dismissKeyboard() {
aTextField.resignFirstResponder()
}
Un trazador de líneas
self.view.addTapGesture(UITapGestureRecognizer.init(target: self, action: "endEditing:"))
Utilicé el ejemplo de Barry para mi nuevo desarrollo. ¡Funcionó muy bien! pero tuve que incluir un cambio leve, requerido para descartar el teclado solo para el campo de texto que se está editando.
Entonces, agregué al ejemplo de Barry lo siguiente:
- (void) textFieldDidBeginEditing:(UITextField *)textField
{
_textBeingEdited = textField;
}
-(void) textFieldDidEndEditing:(UITextField *)textField
{
_textBeingEdited = nil;
}
Además, cambié el método hideKeyboard de la siguiente manera:
- (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];
}
Una de las formas más fáciles y cortas es agregar este código a su viewDidLoad
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc]
initWithTarget:self.view
action:@selector(endEditing:)]];
Intenté muchas de las respuestas aquí y no tuve suerte. Mi reconocedor de gestos de toque siempre causaba UIButtons
que no respondiera cuando lo tocaba, incluso cuando configurabacancelsTouchesInView
propiedad del reconocedor de gestos en NO.
Esto es lo que finalmente resolvió el problema:
Tener un ivar:
UITapGestureRecognizer *_keyboardDismissGestureRecognizer;
Cuando un campo de texto comienza a editar, configure el reconocedor de gestos:
- (void) textFieldDidBeginEditing:(UITextField *)textField
{
if(_keyboardDismissGestureRecognizer == nil)
{
_keyboardDismissGestureRecognizer = [[[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissKeyboard)] autorelease];
_keyboardDismissGestureRecognizer.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:_keyboardDismissGestureRecognizer];
}
}
Entonces el truco está en cómo configuras el dismissKeyboard
método:
- (void) dismissKeyboard
{
[self performSelector:@selector(dismissKeyboardSelector) withObject:nil afterDelay:0.01];
}
- (void) dismissKeyboardSelector
{
[self.view endEditing:YES];
[self.view removeGestureRecognizer:_keyboardDismissGestureRecognizer];
_keyboardDismissGestureRecognizer = nil;
}
Supongo que hay algo acerca de sacar la dismissKeyboardSelector
ejecución de la pila de ejecución de manejo táctil ...
Enviar mensaje resignFirstResponder
al archivo de texto que lo puso allí. Por favor, vea esta publicación para más información.
En este ejemplo, aTextField es el único UITextField ... Si hay otros o UITextViews, hay un poco más por hacer.
// 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];
}
Agregue este código en su archivo ViewController.m :
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
En este caso, se puede usar ScrollView y agregarlo TextField
en ScrollView y quiero tocar ScrollView
y luego en Descartar el teclado. Traté de crear un código de muestra por si acaso. Me gusta esto,
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.
}
}
Tu guión gráfico Mira eso al igual que.
Puede usar el método UITapGestureRecongnizer para cerrar el teclado haciendo clic fuera de UITextField. Al usar este método cada vez que el usuario haga clic fuera de UITextField, el teclado se descartará. A continuación se muestra el fragmento de código para usarlo.
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissk)];
[self.view addGestureRecognizer:tap];
//Method
- (void) dismissk
{
[abctextfield resignFirstResponder];
[deftextfield resignFirstResponder];
}