Проблема UIKeyboardWillShowNotification, UIKeyboardWillHideNotification и NSNotificationCenter между версиями iOS

У меня есть несколько полей UITextFields (каждое внутри UITableViewCell). Когда клавиатура запускается из любого текстового поля, мне нужно сделать некоторые анимации, в основном для изменения кадра UITableView. То же самое должно произойти, когда клавиатура скроется.

Я сделал анимацию, так что проблема не в этом.

Теперь я использую NSNotificationCenter, чтобы отловить отображение / скрытие клавиатуры:

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

Проблема в том, что клавиатура видна (используется текстовое поле) и я нажимаю внутри другого текстового поля. Обычно для этого клавиатура не прячется, а остается видимой.

Он отлично работает в iOS 4, но проблема возникает в 3.1.3 (это версия, которую я могу протестировать - возможно, любая версия ниже 3.2). В версиях старше 3.2 изменение фокуса с текстового поля непосредственно на другое текстовое поле приведет к срабатыванию UIKeyboardWillHideNotification и UIKeyboardWillShowNotification.

Кто-нибудь знает способ выполнить некоторую анимацию, когда клавиатура действительно будет показывать / скрывать, без NSNotificationCenter?

Или как я могу решить эту проблему с версиями ниже 3.2?

Спасибо.


person CristiC    schedule 22.07.2011    source источник
comment
На заметку: почти все обновились до iOS 4 и те, кто не редко скачивает или обновляет приложения. Одна альтернатива - переключиться на поддержку только iOS 4 для новых версий. Оказывайте поддержку обоим только в том случае, если ваше приложение не уступает по важности банковскому приложению или у вас есть особая потребность в этом.   -  person Peter DeWeese    schedule 22.07.2011
comment
@ Питер: Согласен с тобой. Только то, что приложение почти готово. Эта небольшая проблема не является для меня реальной причиной поддерживать только устройства iOS4.   -  person CristiC    schedule 22.07.2011


Ответы (3)


Что вы можете сделать, так это установить делегата текстового поля / textview на текущий контроллер представления и реализовать эти 2 метода

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
    _keyboardWillHide = NO;
    return YES;
}

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
    _keyboardWillHide = NO;
    return YES;    
}

После этого в вашем методе, который запускается уведомлением UIKeyboardWillHideNotification, вы можете сделать что-то вроде

if (_keyboardWillHide) {
    // No other textfield/textview was selected so you can animate the tableView
    ...
}
_keyBoardWillHide = YES;

Сообщите мне, если это сработает для вас.

person Mihai Fratu    schedule 25.07.2011
comment
Спасибо, я попробую сегодня вечером и вернусь к вам. - person CristiC; 25.07.2011
comment
Это сработало, но с небольшими изменениями: В вашем ответе _keyBoardWillHide = YES; был в UIKeyboardWillHideNotification. Я перемещал его везде, где был [UITextField resignFirstResponder]; - person CristiC; 27.07.2011
comment
@shim Один для UITextField, другой для UITextView. - person devios1; 26.05.2015

Вместо того, чтобы избегать уведомлений, вы можете установить NSTimer на 0,1 секунды для анимации в одном, а в другом отменить таймер, таким образом, если вы получите UIKeyboardWillHide и UIKeyboardWillShow одновременно, у вас будет возможность отменить таймер. Если вы не получите и то, и другое, таймер обнулится, и анимация будет выполняться.

person Alex Gosselin    schedule 22.07.2011
comment
Это хорошая идея. Но это невозможно сделать, так как это создаст небольшой промежуток (задержку) между анимацией UIKeyboard и моей собственной анимацией. - person CristiC; 23.07.2011
comment
Уведомления всегда срабатывают в предсказуемом порядке? - person Alex Gosselin; 23.07.2011
comment
Вы можете рассмотреть возможность запуска анимации в методе WillHide, затем в методе WillShow проверьте, запущена ли анимация, и прервите ее. Таким образом, если шоу не будет, они будут проведены, иначе их остановят, прежде чем что-нибудь произойдет. Предполагая, что оба метода вызываются быстрым огнем, т. Е. - person Alex Gosselin; 23.07.2011

Рассмотрите возможность использования протокола UITextFieldDelegate. Метод textFieldShouldBeginEditing: срабатывает перед уведомлением и срабатывает каждый раз, когда вы входите в текстовое поле.

person Steve Yung    schedule 22.07.2011