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 forma segura para subprocesos y que la variable estática no sea visible en el exterior. Y es GCD estándar, por lo que no es necesario conocer 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 solo desea saber si el teclado es visible o no, sino qué tan grande es. No todos los teclados tienen el mismo tamaño. Los teclados de iPhone son más pequeños que los de iPad. Entonces querría otra propiedad @property (readonly, nonatomic) CGRect keyboardRect;
que se establece en el método noticeShowKeyboard: como este:
NSValue* value = notification.userInfo [UIKeyboardFrameEndUserInfoKey];
_keyboardRect = value.CGRectValue;
Es importante notar que el rectángulo está en las coordenadas UIWindow y no respeta la rotación de la pantalla. Entonces, la persona que llama convertiría 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 dirá a la aplicación que el teclado está oculto y luego se mostrará nuevamente. Cuando se muestra, lo más probable es que todavía no se hayan rotado otras vistas. Entonces, si observa que el teclado oculta / muestra eventos 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 lo esté.
Por eso es muy importante saber lo que realmente quiere. 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 por sí misma.