2011-07-25 15 views
10

El siguiente código (lo siento por la longitud) muestra un comportamiento extraño en iOS 4.3 (tal vez otras versiones también). En este ejemplo, hay tres UITextField que tienen tres teclados de diferentes tamaños. Si comienza a editar un campo de texto y luego toca "regresar" descartando el teclado, cada vez que se devuelve el tamaño del teclado correctamente en UIKeyboardWillShowNotification y UIKeyboardDidShowNotification usando UIKeyboardFrameBeginUserInfoKey.UIKeyboardWillShowNotification y UIKeyboardDidShowNotification informan mal altura del teclado

ver a continuación:

- (void) keyboardWillShowNotification:(NSNotification *)aNotification

y

- (void) keyboardDidShowNotification:(NSNotification *)aNotification

Tenga en cuenta que este es el comportamiento esperado.

action     reported keyboard size expected keyboard size 
--------------------- ---------------------- ---------------------- 
touch one & return 100      100 
touch two & return 200      200 
touch normal & return 216      216 
n   & return keyboard size(n)  keyboard size(n) 

El comportamiento inesperado es que si comienza a editar un campo de texto, se informa el tamaño del primer teclado (esperado). Cuando toca el segundo campo de texto (sin tocar regresar), se informa el tamaño del primer teclado (inesperado) en lugar del tamaño del segundo. Cuando toca el tercer campo de texto (sin tocar regresar), se informa el tamaño del segundo tamaño del teclado (inesperado) en lugar del tamaño del tercero. Por segunda a enésima vez, parece que informa el tamaño del teclado anterior, no el que se mostrará.

action  reported keyboard size expected keyboard size 
------------ ---------------------- ---------------------- 
touch one  100      100 
touch two  100      200 
touch normal 200      216 
touch one  216      100 
n    keyboard size(n-1)  keyboard size(n) 

antes de enviar en un informe de error, sólo quiero para asegurarse de que yo no he mirado nada más.

FYI afeitar en este tiempo tratando de hacer lo correcto (utilizando UIKeyboardWillShowNotification o UIKeyboardDidShowNotification y UIKeyboardFrameBeginUserInfoKey para obtener el tamaño del teclado) cuando se cambia una vista para que un campo de texto que habría sido oscurecida por un teclado es visible. Referencia:

How to make a UITextField move up when keyboard is present?

iOS Library: Text, Web, and Editing Programming Guide for iOS --> Managing the Keyboard

iOS Library: Scroll View Programming Guide for iOS --> Creating and Configuring Scroll Views

BugVC.h

#import <UIKit/UIKit.h> 

@interface BugVC : UIViewController <UITextFieldDelegate> { 
    UITextField *oneTF; 
    UITextField *twoTF; 
    UITextField *normalTF; 
    UILabel *keyboardWillShowNotificationL; 
    UILabel *keyboardDidShowNotificationL; 
} 

- (void) oneReturnTouchDown:(id)sender; 
- (void) twoReturnTouchDown:(id)sneder; 
- (void) keyboardWillShowNotification:(NSNotification *)aNotification; 
- (void) keyboardDidShowNotification:(NSNotification *)aNotification; 

@end 

BugVC.m

#import "BugVC.h" 

@implementation BugVC 

- (id) init 
{ 
    if (!(self = [super init])) 
    { 
     return self; 
    } 

    // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 
    // One text field with 100 height keyboard 
    oneTF = [[UITextField alloc] initWithFrame:CGRectMake(10, 10, 300, 30)]; 
    oneTF.borderStyle = UITextBorderStyleRoundedRect; 
    oneTF.text = @"100"; 
    oneTF.delegate = self; 
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    // Custom input view for the above text field 
    UIView *oneInputView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 100)]; 
    oneInputView.backgroundColor = [UIColor redColor]; 
    UIButton *oneReturnB = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    oneReturnB.frame = CGRectMake(10, 10, 300, 30); 
    [oneReturnB setTitle:@"return" forState:UIControlStateNormal]; 
    [oneReturnB addTarget:self 
        action:@selector(oneReturnTouchDown:) 
     forControlEvents:UIControlEventTouchDown]; 
    [oneInputView addSubview:oneReturnB]; 
    oneTF.inputView = oneInputView; 
    [oneInputView release]; 
    [self.view addSubview:oneTF]; 

    // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 
    // Two text field with 200 height keyboard 
    twoTF = [[UITextField alloc] initWithFrame:CGRectMake(10, 50, 300, 30)]; 
    twoTF.borderStyle = UITextBorderStyleRoundedRect; 
    twoTF.text = @"200"; 
    twoTF.delegate = self; 
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    // Custom input view for the above text field 
    UIView *twoInputView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 200)]; 
    twoInputView.backgroundColor = [UIColor blueColor]; 
    UIButton *twoReturnB = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    twoReturnB.frame = CGRectMake(10, 10, 300, 30); 
    [twoReturnB setTitle:@"return" forState:UIControlStateNormal]; 
    [twoReturnB addTarget:self 
        action:@selector(twoReturnTouchDown:) 
     forControlEvents:UIControlEventTouchDown]; 
    [twoInputView addSubview:twoReturnB]; 
    twoTF.inputView = twoInputView; 
    [twoInputView release]; 
    [self.view addSubview:twoTF]; 

    // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 
    // normal text field with normal keyboard (216 height keyboard) 
    normalTF = [[UITextField alloc] initWithFrame:CGRectMake(10, 90, 300, 30)]; 
    normalTF.borderStyle = UITextBorderStyleRoundedRect; 
    normalTF.text = @"normal"; 
    normalTF.delegate = self; 
    [self.view addSubview:normalTF]; 

    // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 
    // Label that displays the keyboard height from keyboardWillShowNotification 
    keyboardWillShowNotificationL = [[UILabel alloc] initWithFrame:CGRectMake(10, 130, 300, 30)]; 
    keyboardWillShowNotificationL.font = [UIFont systemFontOfSize:14]; 
    keyboardWillShowNotificationL.text = @"keyboardWillShowNotification kbHeight:"; 
    [self.view addSubview:keyboardWillShowNotificationL]; 

    // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 
    // Label that displays the keyboard height from keyboardDidShowNotification 
    keyboardDidShowNotificationL = [[UILabel alloc] initWithFrame:CGRectMake(10, 170, 300, 30)]; 
    keyboardDidShowNotificationL.font = [UIFont systemFontOfSize:14]; 
    keyboardDidShowNotificationL.text = @"keyboardDidShowNotification kbHeight:"; 
    [self.view addSubview:keyboardDidShowNotificationL]; 

    // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 
    // Register for keyboard notifications. 
    [[NSNotificationCenter defaultCenter] 
    addObserver:self 
     selector:@selector(keyboardWillShowNotification:) 
      name:UIKeyboardWillShowNotification object:nil]; 

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

    return self; 
} 

- (void) dealloc 
{ 
    // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 
    // Deregister for keyboard notifications 
    [[NSNotificationCenter defaultCenter] 
    removeObserver:self 
       name:UIKeyboardWillShowNotification object:nil]; 

    [[NSNotificationCenter defaultCenter] 
    removeObserver:self 
       name:UIKeyboardDidShowNotification object:nil]; 

    [oneTF release]; 
    [twoTF release]; 
    [normalTF release]; 
    [keyboardWillShowNotificationL release]; 
    [keyboardDidShowNotificationL release]; 

    [super dealloc]; 
} 

- (BOOL) textFieldShouldReturn:(UITextField *)textField 
{ 
    [textField resignFirstResponder]; 

    return YES; 
} 

- (void) oneReturnTouchDown:(id)sender 
{ 
    [oneTF.delegate textFieldShouldReturn:oneTF]; 
} 

- (void) twoReturnTouchDown:(id)sneder 
{ 
    [twoTF.delegate textFieldShouldReturn:twoTF]; 
} 

- (void) keyboardWillShowNotification:(NSNotification *)aNotification 
{ 
    NSDictionary *info = [aNotification userInfo]; 
    CGFloat kbHeight = 
     [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height; 

    NSString *string = [[NSString alloc] initWithFormat:@"keyboardWillShowNotification kbHeight: %.2f", kbHeight]; 
    NSLog(@"%@", string); 
    keyboardWillShowNotificationL.text = string; 
    [string release]; 
} 

- (void) keyboardDidShowNotification:(NSNotification *)aNotification 
{ 
    NSDictionary *info = [aNotification userInfo]; 
    CGFloat kbHeight = 
     [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height; 

    NSString *string = [[NSString alloc] initWithFormat:@"keyboardDidShowNotification kbHeight: %.2f", kbHeight]; 
    NSLog(@"%@", string); 
    keyboardDidShowNotificationL.text = string; 
    [string release]; 
} 

@end 

Respuesta

25

Como se informó en this question, la start frame (introducido por UIKeyboardFrameBeginUserInfoKey) es donde el teclado está en el comenzando de la animación. UIKeyboardFrameEndUserInfoKey debería obtener el end frame en su lugar. Presumiblemente, el tamaño también es diferente entre los marcos.

Referencia clave: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIWindow_Class/UIWindowClassReference/UIWindowClassReference.html#//apple_ref/doc/constant_group/Keyboard_Notification_User_Info_Keys

+0

Gracias por señalar que debo utilizar UIKeyboardFrameEndUserInfoKey. Cuando originalmente miré la documentación, no estaba claro para mí cuál era la diferencia entre UIKeyboardFrameBeginUserInfoKey y UIKeyboardFrameEndUserInfoKey. Gracias por la explicación. – mmorris

+0

¡Excelente!Este es un caso oscuro, que acabo de encontrar mezclando teclados estándar y selectores de fecha y afortunadamente encontré tu publicación. ¡El UIKeyboardFrameEndUserInfoKey es el bit crítico de información necesario! –

Cuestiones relacionadas