¿Cómo puedo verificar mediante progtwigción si hay un teclado presente en la aplicación de iOS?

Necesito verificar el estado de la visibilidad del teclado en mi aplicación iOS.

Pseudocódigo:

if(keyboardIsPresentOnWindow) { //Do action 1 } else if (keyboardIsNotPresentOnWindow) { //Do action 2 } 

¿Cómo puedo verificar esta condición?

El código de drawnonward está muy cerca, pero colisiona con el espacio de nombres de UIKit y podría ser más fácil de usar.

 @interface KeyboardStateListener : NSObject { BOOL _isVisible; } + (KeyboardStateListener *)sharedInstance; @property (nonatomic, readonly, getter=isVisible) BOOL visible; @end static KeyboardStateListener *sharedInstance; @implementation KeyboardStateListener + (KeyboardStateListener *)sharedInstance { return sharedInstance; } + (void)load { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; sharedInstance = [[self alloc] init]; [pool release]; } - (BOOL)isVisible { return _isVisible; } - (void)didShow { _isVisible = YES; } - (void)didHide { _isVisible = NO; } - (id)init { if ((self = [super init])) { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(didShow) name:UIKeyboardDidShowNotification object:nil]; [center addObserver:self selector:@selector(didHide) name:UIKeyboardWillHideNotification object:nil]; } return self; } @end 

… o toma el camino más fácil:

Cuando ingresa un campo de texto, se convierte en el primer respondedor y aparece el teclado. Puede verificar el estado del teclado con [myTextField isFirstResponder] . Si vuelve YES , entonces el teclado está activo.

Creo que debes usar las notificaciones que se proporcionan sobre el teclado:

De: http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITextField_Class/Reference/UITextField.html

Notificaciones de teclado

Cuando el sistema muestra u oculta el teclado, publica varias notificaciones de teclado. Estas notificaciones contienen información sobre el teclado, incluido su tamaño, que puede usar para cálculos que implican mover vistas. El registro de estas notificaciones es la única forma de obtener algunos tipos de información sobre el teclado. El sistema entrega las siguientes notificaciones para eventos relacionados con el teclado:

 * UIKeyboardWillShowNotification * UIKeyboardDidShowNotification * UIKeyboardWillHideNotification * UIKeyboardDidHideNotification 

Para obtener más información acerca de estas notificaciones, consulte sus descripciones en UIWindow Class Reference. Para obtener información sobre cómo mostrar y ocultar el teclado, consulte Texto y Web.

Cree un UIKeyboardListener cuando sepa que el teclado no está visible, por ejemplo, llamando [UIKeyboardListener shared] desde applicationDidFinishLaunching .

 @implementation UIKeyboardListener + (UIKeyboardListener) shared { static UIKeyboardListener sListener; if ( nil == sListener ) sListener = [[UIKeyboardListener alloc] init]; return sListener; } -(id) init { self = [super init]; if ( self ) { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(noticeShowKeyboard:) name:UIKeyboardDidShowNotification object:nil]; [center addObserver:self selector:@selector(noticeHideKeyboard:) name:UIKeyboardWillHideNotification object:nil]; } return self; } -(void) noticeShowKeyboard:(NSNotification *)inNotification { _visible = true; } -(void) noticeHideKeyboard:(NSNotification *)inNotification { _visible = false; } -(BOOL) isVisible { return _visible; } @end 

Usar la jerarquía de subvista de ventana como indicación para mostrar el teclado es un truco. Si Apple cambia su implementación subyacente, todas estas respuestas se romperán.

La forma correcta sería monitorear la presentación del teclado y ocultar las notificaciones de toda la aplicación, como dentro de su delegado de la aplicación:

En AppDelegate.h:

 @interface AppDelegate : UIResponder  @property (assign, nonatomic) BOOL keyboardIsShowing; @end 

En AppDelegate.m:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Monitor keyboard status application wide self.keyboardIsShowing = NO; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil]; return YES; } - (void)keyboardWillShow:(NSNotification*)aNotification { self.keyboardIsShowing = YES; } - (void)keyboardWillBeHidden:(NSNotification*)aNotification { self.keyboardIsShowing = NO; } 

Entonces puedes verificar usando:

 BOOL keyboardIsShowing = ((AppDelegate*)[UIApplication sharedApplication].delegate).keyboardIsShowing; 

Cabe señalar que las notificaciones de mostrar / ocultar del teclado no se dispararán cuando el usuario esté usando un bluetooth o un teclado externo.

Implementación de Swift 3

  import Foundation class KeyboardStateListener: NSObject { static let shared = KeyboardStateListener() var isVisible = false func start() { NotificationCenter.default.addObserver(self, selector: #selector(didShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(didHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil) } func didShow() { isVisible = true } func didHide() { isVisible = false } } 

Esto es de la Guía de progtwigción de texto de iOS publicada por Apple aquí: https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html

Básicamente llame “registerForKeyBoardNotifications” en su ViewDidLoad. Luego, cada vez que el teclado se activa, se invoca “keyboardWasShown”. Y cada vez que el teclado desaparece, se invoca “keyboardWillBeHidden”.

 // Call this method somewhere in your view controller setup code. - (void)registerForKeyboardNotifications { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil]; } // Called when the UIKeyboardDidShowNotification is sent. - (void)keyboardWasShown:(NSNotification*)aNotification { NSLog(@"Keyboard is active."); NSDictionary* info = [aNotification userInfo]; CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0); scrollView.contentInset = contentInsets; scrollView.scrollIndicatorInsets = contentInsets; // If active text field is hidden by keyboard, scroll it so it's visible // Your app might not need or want this behavior. CGRect aRect = self.view.frame; aRect.size.height -= kbSize.height; if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) { [self.scrollView scrollRectToVisible:activeField.frame animated:YES]; } } // Called when the UIKeyboardWillHideNotification is sent - (void)keyboardWillBeHidden:(NSNotification*)aNotification { NSLog(@"Keyboard is hidden"); UIEdgeInsets contentInsets = UIEdgeInsetsZero; scrollView.contentInset = contentInsets; scrollView.scrollIndicatorInsets = contentInsets; } 

Ahora en iOS8, esta solución, por supuesto, no funciona. Fue escrito inicialmente para IOS4 / 5.

Prueba esta solución:

 - (BOOL) isKeyboardOnScreen { BOOL isKeyboardShown = NO; NSArray *windows = [UIApplication sharedApplication].windows; if (windows.count > 1) { NSArray *wSubviews = [windows[1] subviews]; if (wSubviews.count) { CGRect keyboardFrame = [wSubviews[0] frame]; CGRect screenFrame = [windows[1] frame]; if (keyboardFrame.origin.y+keyboardFrame.size.height == screenFrame.size.height) { isKeyboardShown = YES; } } } return isKeyboardShown; } 

Algunas observaciones:

El patrón recomendado para un objeto singleton sería el siguiente. dispatch_once se asegura de que la clase se inicialice una vez de una manera segura para la ejecución de subprocesos y la variable estática no sea visible fuera. Y es GCD estándar, por lo que no es necesario saber detalles de bajo nivel de Objective-C.

 + (KeyboardStateListener *)sharedInstance { static KeyboardStateListener* shared; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ shared = [[KeyboardStateListener alloc] init]; // Other initialisations }); return shared; } 

Por lo general, no desea saber si el teclado está visible o no, sino qué tan grande es. Los teclados no tienen todos el mismo tamaño. Los teclados de iPhone son más pequeños que los teclados de iPad. Entonces querrías otra propiedad @property (readonly, nonatomic) CGRect keyboardRect; que se establece en el método noticeShowKeyboard: así:

 NSValue* value = notification.userInfo [UIKeyboardFrameEndUserInfoKey]; _keyboardRect = value.CGRectValue; 

Es importante notar que el rectángulo está en las coordenadas de la ventana UI y no respeta la rotación de la pantalla. Entonces la persona que llama debería convertir ese rectángulo llamando

 KeyboardStateListener* listener = [KeyboardStateListener sharedInstance]; CGRect windowRect = listener.keyboardRect; CGRect viewRect = [myView convertRect:windowRect fromView:self.window]; 

Si el usuario gira la pantalla mientras el teclado está visible, se le informará a la aplicación que el teclado está oculto y luego se volverá a mostrar. Cuando se muestra, otras vistas probablemente no se hayan girado aún. Por lo tanto, si observa los eventos hide / show del teclado usted mismo, convierta las coordenadas cuando realmente las necesite, no en la notificación.

Si el usuario divide o desacopla el teclado, o usa un teclado de hardware, las notificaciones siempre mostrarán el teclado como oculto. Desacoplar o fusionar el teclado enviará una notificación de “teclado mostrado”.

El oyente debe inicializarse mientras el teclado está oculto; de lo contrario, se perderá la primera notificación, y se asumirá que el teclado está oculto cuando no está.

Entonces, es muy importante saber lo que realmente quieres. Este código es útil para mover cosas fuera del camino del teclado (con un teclado dividido o desacoplado, eso es responsabilidad del usuario). No le dice si el usuario puede ver un teclado en la pantalla (en el caso de un teclado dividido). No le dice si el usuario puede escribir (por ejemplo, cuando hay un teclado de hardware). Mirar otras ventanas no funciona si la aplicación crea otras ventanas.

Y he aquí cómo hacerlo en Swift:

  func registerForKeyboardNotifications() { NSNotificationCenter.defaultCenter().addObserver( self, selector: "keyboardWasShown:", name: UIKeyboardDidShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver( self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil) } func keyboardWasShown(notification: NSNotification) { println("Keyboard was shown"); } func keyboardWillBeHidden(notification: NSNotification) { println("Keyboard was dismissed"); } 

No te olvides de cancelar el registro:

  override func viewWillDisappear(animated: Bool) { NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardDidShowNotification, object: nil) NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil) } 

Y si desea descartar el teclado al presionar el botón “Volver”:

 class ViewController: UIViewController, UITextFieldDelegate { @IBOutlet weak var yourTextField: UITextField! override func viewDidLoad() { super.viewDidLoad() registerForKeyboardNotifications() yourTextField.delegate = self } func textFieldShouldReturn(textField: UITextField!) -> Bool { self.view.endEditing(true); return false; } } 

Implementación rápida :

 class KeyboardStateListener: NSObject { static var shared = KeyboardStateListener() var isVisible = false func start() { let nc = NSNotificationCenter.defaultCenter() nc.addObserver(self, selector: #selector(didShow), name: UIKeyboardDidShowNotification, object: nil) nc.addObserver(self, selector: #selector(didHide), name: UIKeyboardDidHideNotification, object: nil) } func didShow() { isVisible = true } func didHide() { isVisible = false } } 

Debido a que swift no ejecuta el método de carga de clase al inicio, es importante iniciar este servicio en el inicio de la aplicación:

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool { ... KeyboardStateListener.shared.start() } 

Prueba esta función

 BOOL UIKeyboardIsVisible(){ BOOL keyboardVisible=NO; // Locate non-UIWindow. UIWindow *keyboardWindow = nil; for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) { if (![[testWindow class] isEqual:[UIWindow class]]) { keyboardWindow = testWindow; break; } } // Locate UIKeyboard. for (UIView *possibleKeyboard in [keyboardWindow subviews]) { // iOS 4 sticks the UIKeyboard inside a UIPeripheralHostView. if ([[possibleKeyboard description] hasPrefix:@" 

}

desde: iOS: ¿Cómo acceder al `UIKeyboard`?

BOOL isTxtOpen = [txtfieldObjct isFirstReponder]. Si vuelve SÍ, entonces el teclado está activo.

Para consultar el teclado meteorológico aparece, podemos utilizar las notificaciones predefinidas del teclado.

UIKeyboardDidShowNotification, UIKeyboardDidHideNotification

Por ejemplo, puedo usar el siguiente código para escuchar la notificación del teclado

// Escucha las apariciones y desapariciones del teclado

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil]; 

en los métodos puedo obtener notificaciones

 - (void)keyboardDidShow: (NSNotification *) notifyKeyBoardShow{ // key board is closed } - (void)keyboardDidHide: (NSNotification *) notifyKeyBoardHide{ // key board is opened } 

Esta es mi solución, encapsula todo en un único método estático y puede llamarlo a cualquier parte para verificar:

 +(BOOL)isKeyboardVisible{ static id tokenKeyboardWillShow = nil; static id tokenKeyboardWillHide = nil; static BOOL isKbVisible = NO; @synchronized (self) { if (tokenKeyboardWillShow == nil){ tokenKeyboardWillShow = [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) { @synchronized (self) { isKbVisible = YES; } }]; } if (tokenKeyboardWillHide == nil){ tokenKeyboardWillHide = [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillHideNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) { @synchronized (self) { isKbVisible = NO; } }]; } } return isKbVisible; } 

Puede verificar iterativamente todas las textviews, textfields y labels en las subvistas de una vista principal para ver si alguno es el primero en responder con algo como esto:

 -(BOOL)isKeyboardActiveInView:(UIView *)view { for (UIView *anyView in [view subviews]) { if ([anyView isKindOfClass:[UITextField class]]) { if (((UITextField *)anyView).isFirstResponder) { return YES; } } else if ([anyView isKindOfClass:[UILabel class]]) { if (((UILabel *)anyView).isFirstResponder) { return YES; } } else if ([anyView isKindOfClass:[UITextView class]]) { if (((UITextView *)anyView).isFirstResponder) { return YES; } } else { if ([self isKeyboardActiveInView:anyView]) { return YES; } } } return NO; } 

Creo que esto puede ser útil,

 +(BOOL)isKeyBoardInDisplay { BOOL isExists = NO; for (UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows]) { if ([[keyboardWindow description] hasPrefix:@" 

Gracias,

Naveen Shan