UIKeyboardWillShowNotification и UIKeyboardDidShowNotification сообщают о неправильной высоте клавиатуры - PullRequest
11 голосов
/ 26 июля 2011

Следующий код (извините за длину) отображает странное поведение в iOS 4.3 (возможно, и в другой версии). В этом примере есть три UITextField с тремя клавиатурами разных размеров. Если вы начинаете редактировать одно текстовое поле, а затем нажимаете «возврат», отклоняя клавиатуру, каждый раз, когда размер клавиатуры возвращается правильно в UIKeyboardWillShowNotification и UIKeyboardDidShowNotification с использованием UIKeyboardFrameBeginUserInfoKey.

см. Ниже:

- (void) keyboardWillShowNotification:(NSNotification *)aNotification

и

- (void) keyboardDidShowNotification:(NSNotification *)aNotification

Обратите внимание, что это ожидаемое поведение.

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)

Неожиданное поведение - если вы начинаете редактировать текстовое поле, то сообщается размер ожидаемой первой клавиатуры. Когда вы касаетесь второго текстового поля (не касаясь возврата), размер первой клавиатуры сообщается (неожиданно) вместо размера второй. При прикосновении к третьему текстовому полю (без прикосновения к возврату) сообщается о размере второго размера клавиатуры (неожиданно) вместо размера третьего. Второй и n-й раз кажется, что он сообщает размер предыдущей клавиатуры, а не тот, который будет отображаться.

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)

Прежде чем отправить отчет об ошибке, я просто хочу убедиться, что я ничего не просмотрел.

К вашему сведению, я наткнулся на это, пытаясь сделать правильные вещи (используя UIKeyboardWillShowNotification или UIKeyboardDidShowNotification и UIKeyboardFrameBeginUserInfoKey, чтобы получить размер клавиатуры) при смещении вида так, чтобы текстовое поле было затенено клавиатура видна. Справка:

Как заставить UITextField двигаться вверх при наличии клавиатуры?

Библиотека iOS: Руководство по программированию текста, Интернета и редактирования для iOS -> Управление клавиатурой

Библиотека iOS: Руководство по программированию вида прокрутки для iOS -> Создание и настройка видов прокрутки

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

1 Ответ

26 голосов
/ 11 октября 2011

Как сообщается в , этот вопрос , start frame (обозначенный UIKeyboardFrameBeginUserInfoKey) - это то, где клавиатура находится в начале анимации. UIKeyboardFrameEndUserInfoKey вместо этого должен получить end frame. Предположительно, размер также отличается между кадрами.

Ключевой номер: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIWindow_Class/UIWindowClassReference/UIWindowClassReference.html#//apple_ref/doc/constant_group/Keyboard_Notification_User_Info_Keys

...