UITextField и уведомления о клавиатуре - странный порядок

Итак, я настроил уведомление о событии появления клавиатуры. Теперь рассмотрим UITextView и UITextField.

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

Селектор:

- (void)keyboardWillShow:(NSNotification *)notification {

        keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
}

В случае UITextView метод делегата - (void)textViewDidBeginEditing:(UITextView *)textView запускается ПОСЛЕ метода keyboardWillShow:. Так что клавиатура имеет фактический размер клавиатуры, и я могу использовать ее внутри метода делегата textview.

Однако в случае UITextField соответствующий метод делегата - (void)textFieldDidBeginEditing:(UITextField *)textField запускается ПЕРЕД методом keyboardWillShow:.

Почему это так? Как получить клавиатуру CGSize в случае текстового поля, так как теперь она просто возвращает ноль, потому что делегат текстового поля вызывается первым, а не селектор клавиатуры.

Ответы

Ответ 1

Странно... Похоже на ошибку Apple.

Возможно, вы могли бы задержать клавиатуру? Здесь мое, к сожалению, очень грязное предложение "обойти" - вы можете отправить уведомление, когда текстовое поле выбрано, но только на самом деле начните редактирование доли секунды позже, чтобы текстовое поле было действительно известно до keyboardWillShow:. называется. Например:

-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField {

    // Notification corresponding to "textFieldSelected:" method
    [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_TEXT_FIELD_SELECTED object:nil userInfo:[[NSDictionary alloc] initWithObjectsAndKeys:textField, @"textField", nil]];

    // "textFieldReallyShouldBeginEditing" is initially set as FALSE elsewhere in the code before the text field is manually selected
    if (textFieldReallyShouldBeginEditing)
        return YES;
    else
        return NO:
}

- (void)textFieldSelected:(NSNotification*)notification {

    // Done in a separate method so there a guaranteed delay and "textFieldReallyShouldBeginEditing" isn't set to YES before "textFieldShouldBeginEditing:" returns its boolean. 
    [self performSelector:@selector(startTextFieldReallyEditing:) withObject:(UITextField*)notification[@"textField"] afterDelay:.01];
}

- (void)startTextFieldReallyEditing:(UITextField*)textField {
    textFieldReallyShouldBeginEditing = YES;

    // To trigger the keyboard
    [textField becomeFirstResponder];
}

Затем, в зависимости от того, как вы создаете уведомление, вы можете вставить значение этого теперь известного текстового поля еще до того, как оно начнет редактирование.

Ответ 2

У меня была такая же проблема. Попробуйте использовать:

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView