2012-05-25 12 views
9

Estoy creando una aplicación similar a la aplicación de iMessage del iPad que hace mensajes. De modo que hay una vista de entrada anclada en la parte inferior de la vista de mensaje y la vista de accesorio de entrada cuando se muestra el teclado. Además, la vista del mensaje debe redimensionarse correctamente cuando se muestra el teclado mientras está acoplado o desacoplado.Teclado dividido de iPad

El problema que tengo es que los datos de notificación que provienen de UIKeyboardWillChangeFrameNotification no son consistentes.

En primer lugar, hay 3 formas en que el usuario puede desacoplar el teclado:

  1. Presione y mantenga pulsada la tecla inferior derecha, a continuación, se deslizan hacia arriba
  2. Pulse y mantenga pulsada la tecla inferior derecha, cuando aparezca el menú, seleccionar "desacoplar"
  3. Presione y mantenga pulsada la tecla inferior derecha, cuando aparezca el menú, seleccionar "split"

Para el caso # 1, los datos de notificación de UIKeyboardWillChangeFrameNotification es consistir ent. Estos son los datos:

userInfo = { 
    UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 0}, {768, 304}}"; 
} 

Para el caso # 2 y # 3 los datos son inconsistentes, aquí es lo que recibo:

userInfo = { 
    UIKeyboardAnimationCurveUserInfoKey = 0; 
    UIKeyboardAnimationDurationUserInfoKey = "0.25"; 
    UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {768, 304}}"; 
    UIKeyboardCenterBeginUserInfoKey = "NSPoint: {384, 872}"; 
    UIKeyboardCenterEndUserInfoKey = "NSPoint: {384, 1136}"; 
    UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 0}, {768, 304}}"; 
    UIKeyboardFrameChangedByUserInteraction = 0; 
    UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, -264}, {768, 304}}"; 
} 

Lo que es extraño es que cuando escucho a UIKeyboardDidChangeFrameNotification bajo la causa # 2 o # 3, los datos vienen como se esperaba:

userInfo = { 
    UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 0}, {768, 304}}"; 
} 

¿Por qué los datos de notificación son diferentes? ¿Alguien encontró una forma clara de detectar los eventos de teclado dividido?

Respuesta

3

Ningún método claro no tiene.

se resuelve este problema en los siguientes pasos:

  1. Obtener orientación actual.
  2. Si la orientación es Horizontal, entonces obtengo altura de UIKeyboardFrameEndUserInfoKey. debe ser igual a 216. Significa que el teclado está en modo Split, Else no;
  3. Si la orientación es Vertical, entonces obtengo altura de UIKeyboardFrameEndUserInfoKey. debe ser igual a 216. Significa que el teclado está en modo Split, Else no;

Actualizo mi gist for example. Con el método convertRect.

+0

Esto va a hacer que sea más difícil desde que se presenta el iPad Mini. Ni siquiera he tocado iOS 7 todavía ... –

+2

sin diferencia. 216 no es píxeles, su parmetro de punto es independiente de la resolucin. Pero esto no funciona con iPhone 4s y 5. Y iPhone no tiene teclado dividido. Ellos cambian el factor de forma. – Bimawa

+0

Tenga cuidado, esta no es una buena solución. Las alturas de los teclados cambian según la configuración regional, ios y el dispositivo. – capikaw

1

Esta es una forma algo hacky, pero confiable para determinar si el teclado está dividido.

NSArray *classPath = @[ 
    @"KeyboardAutomatic", 
    @"KeyboardImpl", 
    @"KeyboardLayoutStar", 
    @"KBKeyplaneView", 
    @"KBSplitImageView" 
]; 
UIView *splitView = textField.inputAccessoryView.superview; 
for (NSString *className in classPath) { 
    for (UIView *subview in splitView.subviews) { 
    if ([NSStringFromClass([subview class]) rangeOfString:className].location != NSNotFound) { 
     splitView = subview; 
     break; 
    } 
    } 
} 
BOOL isSplit = [splitView.subviews count] > 1; 

Obviamente para que esto funcione es necesario un UITextField/UITextView con un no-nil inputAccessoryView (sólo se puede utilizar una vista vacía para eso).

Nota: El comportamiento detextField.inputAccessoryView.superview es bastante fastidioso, y por lo general depende del teclado después de haber sido representada una vez antes de llamar superview. También para pasar el proceso de envío de App Store eliminé el prefijo 'UI' de los nombres privados de clase.Eso no es garantía de que Apple no marque su aplicación, pero este enfoque se ha utilizado con éxito anteriormente.

Solo lo he probado en iOS7, pero si no funciona en otras versiones de iOS, se podrían utilizar enfoques similares.

+0

esto podría funcionar, pero ¿por qué accede a las subvistas 0 0 1 0? –

+0

Porque recorre la jerarquía de vista buscando una clase privada que realmente renderice el teclado. Utilicé [Revelar] (http://revealapp.com) para ver el estado de la vista del teclado. Ver [aquí] (http://imgur.com/v8rFMKP). – cagey

+0

Es claramente una mala idea usar este código exacto en producción, pero es de esperar que la respuesta aún pueda ser útil para algunas personas. – cagey

Cuestiones relacionadas