objective c - framework - ¿Una forma fácil de descartar el teclado?
cocoa touch framework (30)
@Nicholas Riley & @Kendall Helmstetter Geln & @cannyboy:
¡Absolutamente brillante!
Gracias.
Teniendo en cuenta sus consejos y los consejos de otros en este hilo, esto es lo que he hecho:
Lo que parece cuando se usa:
[[self appDelegate] dismissKeyboard];
(nota: agregué appDelegate como una adición a NSObject para que pueda usarlo en cualquier parte)
Lo que parece debajo del capó:
- (void)dismissKeyboard
{
UITextField *tempTextField = [[[UITextField alloc] initWithFrame:CGRectZero] autorelease];
tempTextField.enabled = NO;
[myRootViewController.view addSubview:tempTextField];
[tempTextField becomeFirstResponder];
[tempTextField resignFirstResponder];
[tempTextField removeFromSuperview];
}
EDITAR
Enmienda a mi respuesta para incluir tempTextField.enabled = NO;
. La desactivación del campo de texto evitará que se UIKeyboardWillShowNotification
notificaciones de teclado UIKeyboardWillShowNotification
y UIKeyboardWillHideNotification
caso de que confíe en estas notificaciones en toda la aplicación.
Tengo bastantes controles dispersos a lo largo de muchas celdas de la mesa en mi mesa, y me preguntaba si hay una forma más fácil de descartar el teclado sin tener que recorrer todos mis controles y renunciar a todos como el primer respondedor. Supongo que la pregunta es ... ¿Cómo obtendría la primera respuesta actual al teclado?
Agregue un reconocedor de gestos de toque a su vista. Y defínalo ibaction
tu archivo .m será como
- (IBAction)hideKeyboardGesture:(id)sender {
NSArray *windows = [UIApplication sharedApplication].windows;
for(UIWindow *window in windows) [window endEditing:true];
[[UIApplication sharedApplication].keyWindow endEditing:true];
}
Ha funcionado para mi
Debe enviar endEditing:
a la ventana de trabajo siendo la subclase de UIView
[[UIApplication sharedApplication].windows.firstObject endEditing:NO];
En Swift 3 puedes hacer lo siguiente.
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
En el archivo de encabezado de su controlador de vista, agregue <UITextFieldDelegate>
a la definición de la interfaz de su controlador para que se ajuste al protocolo de delegado de UITextField ...
@interface someViewController : UIViewController <UITextFieldDelegate>
... En el archivo de implementación del controlador (.m) agregue el siguiente método, o el código que contiene si ya tiene un método viewDidLoad ...
- (void)viewDidLoad
{
// Do any additional setup after loading the view, typically from a nib.
self.yourTextBox.delegate = self;
}
... Luego, vincule su Cuadro de texto a su campo de texto real
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField
{
if (theTextField == yourTextBox) {
[theTextField resignFirstResponder];
}
return YES;
}
En veloz
self.view.endEditing(true)
Esta es una solución para hacer que el teclado desaparezca cuando se pulsa return
en cualquier campo de texto, agregando código en un lugar (así que no tiene que agregar un controlador para cada campo de texto):
considera este escenario:
Tengo un viewcontroller
con dos campos de texto (nombre de usuario y contraseña). y el viewcontroller
implementa el protocolo UITextFieldDelegate
hago esto en viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
username.delegate = self;
password.delegate = self;
}
y el controlador de vista implementa el método opcional como
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
e independientemente del campo de texto en el que se encuentre, tan pronto como presiono Intro en el teclado, ¡se desactiva!
En su caso, lo mismo funcionaría siempre y cuando establezca a todos los delegados del campo de texto en uno mismo e implemente textFieldShouldReturn
Esto es lo que uso en mi código. ¡Funciona a las mil maravillas!
En su viewcontroller.h agregue:
@property (nonatomic) UITapGestureRecognizer *tapRecognizer;
Ahora en el archivo .m, agregue esto a su función ViewDidLoad:
- (void)viewDidLoad {
//Keyboard stuff
tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapAnywhere:)];
tapRecognizer.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:tapRecognizer];
}
Además, agregue esta función en el archivo .m:
- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
[self.view endEditing:YES];
}
Guarda esto en alguna clase de utilidad.
+ (void)dismissKeyboard {
[self globalResignFirstResponder];
}
+ (void) globalResignFirstResponder {
UIWindow * window = [[UIApplication sharedApplication] keyWindow];
for (UIView * view in [window subviews]){
[self globalResignFirstResponderRec:view];
}
}
+ (void) globalResignFirstResponderRec:(UIView*) view {
if ([view respondsToSelector:@selector(resignFirstResponder)]){
[view resignFirstResponder];
}
for (UIView * subview in [view subviews]){
[self globalResignFirstResponderRec:subview];
}
}
Incluso más simple que la respuesta de Meagar
sobrescribir los touchesBegan:withEvent:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[textField resignFirstResponder];`
}
Esto dismiss the keyboard
cuando toque cualquier parte del background
.
La forma más fácil es llamar al método.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if(![txtfld resignFirstResponder])
{
[txtfld resignFirstResponder];
}
else
{
}
[super touchesBegan:touches withEvent:event];
}
La mejor manera de descartar el teclado de UITableView y UIScrollView es:
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag
La respuesta de Jeremy no me funcionó del todo, creo que porque tenía una pila de navegación en una vista de pestaña con un diálogo modal encima. Estoy usando lo siguiente ahora mismo y está funcionando para mí, pero su millaje puede variar.
// dismiss keyboard (mostly macro)
[[UIApplication sharedApplication].delegate dismissKeyboard]; // call this in your to app dismiss the keybaord
// --- dismiss keyboard (in indexAppDelegate.h) (mostly macro)
- (void)dismissKeyboard;
// --- dismiss keyboard (in indexAppDelegate.m) (mostly macro)
// do this from anywhere to dismiss the keybard
- (void)dismissKeyboard { // from: http://.com/questions/741185/easy-way-to-dismiss-keyboard
UITextField *tempTextField = [[UITextField alloc] initWithFrame:CGRectZero];
UIViewController *myRootViewController = <#viewController#>; // for simple apps (INPUT: viewController is whatever your root controller is called. Probably is a way to determine this progragrammatically)
UIViewController *uivc;
if (myRootViewController.navigationController != nil) { // for when there is a nav stack
uivc = myRootViewController.navigationController;
} else {
uivc = myRootViewController;
}
if (uivc.modalViewController != nil) { // for when there is something modal
uivc = uivc.modalViewController;
}
[uivc.view addSubview:tempTextField];
[tempTextField becomeFirstResponder];
[tempTextField resignFirstResponder];
[tempTextField removeFromSuperview];
[tempTextField release];
}
Muchas respuestas demasiado complicadas aquí, tal vez porque no es fácil encontrarlas en la documentación de iOS. JosephH lo tenía justo arriba:
[[view window] endEditing:YES];
No es bonito, pero la forma en que renuncio al primer Contestador cuando no sé lo que el respondedor es:
Cree un UITextField, ya sea en IB o programáticamente. Hazlo oculto. Enlázalo a tu código si lo hiciste en IB. Luego, cuando desea descartar el teclado, cambia el respondedor al campo de texto invisible y lo abandona de inmediato:
[self.invisibleField becomeFirstResponder];
[self.invisibleField resignFirstResponder];
Odio que no haya una forma "global" de descartar el teclado mediante programación sin usar llamadas API privadas. Con frecuencia, tengo la necesidad de descartar el teclado programáticamente sin saber qué objeto es el primer respondedor. He recurrido a inspeccionar el self
utilizando la API de tiempo de ejecución de Objective-C, enumerando todas sus propiedades, extrayendo las que son del tipo UITextField
y enviándoles el mensaje resignFirstResponder
.
No debería ser tan difícil hacer esto ...
Para descartar un teclado después de que el teclado haya aparecido, hay 2 casos ,
cuando el UITextField está dentro de un UIScrollView
cuando el UITextField está fuera de un UIScrollView
2. Cuando el UITextField está fuera de un UIScrollView anula el método en su subclase UIViewController
También debe agregar delegado para todos UITextView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
- En una vista de desplazamiento, Tocar fuera no activará ningún evento , por lo que, en ese caso, use un Reconocedor de gestos de toque , Arrastre y suelte un UITapGesture para la vista de desplazamiento y cree una Acción de IB para él .
para crear una IBAction, presione ctrl + clic en UITapGesture y arrástrelo al archivo .h de viewcontroller.
Aquí he nombrado tappedEvent como mi nombre de acción
- (IBAction)tappedEvent:(id)sender {
[self.view endEditing:YES]; }
La información proporcionada anteriormente se deriva del siguiente enlace, consulte para obtener más información o póngase en contacto conmigo si no entiende los datos de Abouve.
http://samwize.com/2014/03/27/dismiss-keyboard-when-tap-outside-a-uitextfield-slash-uitextview/
Para ser honesto, no estoy loco por ninguna de las soluciones propuestas aquí. Encontré una buena forma de usar un TapGestureRecognizer que creo que llega al corazón de su problema: cuando hace clic en cualquier cosa que no sea el teclado, descarte el teclado.
En viewDidLoad, regístrese para recibir notificaciones de teclado y cree un UITapGestureRecognizer:
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil]; [nc addObserver:self selector:@selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil]; tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapAnywhere:)];
Añadir el teclado mostrar / ocultar respondedores. Allí agrega y elimina TapGestureRecognizer a la UIView que debería descartar el teclado cuando se toca. Nota: No tiene que agregarlo a todas las subvistas o controles.
-(void) keyboardWillShow:(NSNotification *) note { [self.view addGestureRecognizer:tapRecognizer]; } -(void) keyboardWillHide:(NSNotification *) note { [self.view removeGestureRecognizer:tapRecognizer]; }
El TapGestureRecognizer llamará a su función cuando reciba un toque y usted puede descartar el teclado de esta manera:
-(void)didTapAnywhere: (UITapGestureRecognizer*) recognizer { [textField resignFirstResponder]; }
Lo bueno de esta solución es que solo filtra por Taps, no swipes. Por lo tanto, si tiene contenido de desplazamiento sobre el teclado, los deslizadores aún se desplazarán y dejarán el teclado en pantalla. Al eliminar el reconocedor de gestos después de que el teclado se haya ido, los futuros toques en su vista se manejan normalmente.
Puede enviar una acción dirigida nula a la aplicación, renunciará al primer respondedor en cualquier momento sin tener que preocuparse por qué vista tiene actualmente el estado del primer respondedor.
C objetivo:
[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];
Swift 3.0:
UIApplication.shared.sendAction(#selector(resignFirstResponder), to: nil, from: nil, for: nil)
Las acciones dirigidas nulas son comunes en Mac OS X para los comandos de menú, y aquí hay un uso para ellos en iOS.
Puede forzar que la vista de edición actual renuncie a su primer estado de respuesta con [view endEditing:YES]
. Esto oculta el teclado.
A diferencia de -[UIResponder resignFirstResponder]
, -[UIView endEditing:]
buscará en las subvistas para encontrar el primer respondedor actual. Así que puedes enviarlo a tu vista de nivel superior (por ejemplo, self.view
en un UIViewController
) y hará lo correcto.
(Esta respuesta incluía un par de otras soluciones, que también funcionaron pero eran más complicadas de lo necesario. Las he eliminado para evitar confusiones).
Puede iterar recursivamente a través de subvistas, almacenar una matriz de todos los UITextFields, y luego recorrerlos y renunciar a todos.
No es realmente una gran solución, especialmente si tiene muchas subvistas, pero para aplicaciones simples debería hacer el truco.
Resolví esto de una manera mucho más complicada, pero mucho más eficaz, pero utilizando un administrador / singleton para el motor de animación de mi aplicación, y cada vez que un campo de texto se convertía en el respondedor, le asignaba una estática que obtendría barrido (resignado) basado en ciertos otros eventos ... es casi imposible para mí explicar en un párrafo.
Sea creativo, solo me tomó 10 minutos pensar en esto para mi aplicación después de encontrar esta pregunta.
Sí, endEditing es la mejor opción. Y desde iOW 7.0, UIScrollView
tiene una característica interesante para cerrar el teclado al interactuar con la vista de desplazamiento. Para lograr esto, puede establecer la propiedad keyboardDismissMode
de UIScrollView
.
Configure el modo de desconexión del teclado como:
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag
Tiene algunos otros tipos. Echa un vistazo a este documento de manzana .
Subclase sus campos de texto ... y también vistas de texto
En la subclase ponemos este código.
-(void)conformsToKeyboardDismissNotification{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissKeyBoard) name:KEYBOARD_DISMISS object:nil];
}
-(void)deConformsToKeyboardDismissNotification{
[[NSNotificationCenter defaultCenter] removeObserver:self name:KEYBOARD_DISMISS object:nil];
}
- (void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self resignFirstResponder];
}
En los campos de texto delegados (de manera similar para los delegados de vista de texto)
-(void)textFieldDidBeginEditing:(JCPTextField *)textField{
[textField conformsToKeyboardDismissNotification];
}
- (void)textFieldDidEndEditing:(JCPTextField *)textField{
[textField deConformsToKeyboardDismissNotification];
}
Todo listo. Ahora solo publique la notificación desde cualquier lugar en su código. Renunciará a cualquier teclado.
Sugerencia rápida sobre cómo descartar el teclado en iOS cuando un usuario toca cualquier parte de la pantalla fuera del UITextField o del teclado. Teniendo en cuenta la cantidad de bienes raíces que puede ocupar el teclado de iOS, tiene sentido tener una forma fácil e intuitiva para que los usuarios descarten el teclado.
Aquí hay un enlace
También es posible que deba anular UIViewController deshabilitaAutomaticKeyboardDismissal para que esto funcione en algunos casos. Es posible que tenga que hacer esto en el controlador UINavigation si tiene uno.
Tienes que usar uno de estos métodos,
[self.view endEditing:YES];
o
[self.textField resignFirstResponder];
Tratar:
[self.view endEditing:YES];
Un método ligeramente más robusto que necesitaba usar recientemente:
- (void) dismissKeyboard {
NSArray *windows = [UIApplication sharedApplication].windows;
for(UIWindow *window in windows) [window endEditing:true];
// Or if you''re only working with one UIWindow:
[[UIApplication sharedApplication].keyWindow endEditing:true];
}
Encontré que algunos de los otros métodos "globales" no funcionaban (por ejemplo, UIWebView
y WKWebView
negaron a renunciar).
Un mejor enfoque es tener algo que "robe" el primer estado de respuesta.
Dado que UIApplication es una subclase de UIResponder, puedes probar:
[[UIApplication sharedApplication] becomeFirstResponder]
[[UIApplication sharedApplication] resignFirstResponder]
Si falla, cree un nuevo UITextField con un marco de tamaño cero, agréguelo a una vista en algún lugar y haga algo similar (haga clic en "Seguir" por la renuncia).
Y en veloz podemos hacer.
UIApplication.sharedApplication().sendAction("resignFirstResponder", to: nil, from: nil, forEvent: nil)