Устранение проблем с клавиатурой FirstResponder

Итак, я делаю приложение, и у меня возникают проблемы с удалением клавиатуры из UISearchBar и UITextFields. Вот структура моего приложения:

NavigationController -> ViewC1 - (модально) -> ViewC2 - (модально) -> ViewC3

У меня есть окно поиска в ViewC1, и при нажатии кнопки «Поиск» на клавиатуре клавиатура убирается, это работает нормально. Однако, если я вернусь в ViewC1 после того, как был в ViewC3, клавиатура больше не исчезает при нажатии кнопки «Поиск». В методе делегата панели поиска я поставил следующее:

- (void) searchBarSearchButtonClicked:(UISearchBar *)search
{
if ([search isFirstResponder]) {
    [search resignFirstResponder];
  } else {
    [search becomeFirstResponder];
    [search resignFirstResponder];
  }
}

Это не решает проблему, и я не уверен, почему клавиатура не закрывается. Для справки: при возврате к исходному ViewC1 ViewC3 закрывается следующим образом:

UIViewController *parent = self.presentingViewController;
[parent.presentingViewController dismissViewControllerAnimated:YES completion:nil];

Любая помощь приветствуется, спасибо.


person sj.cleaver    schedule 08.04.2013    source источник
comment
Я рекомендую отладить метод нажатия кнопки поиска. Панель поиска и ее делегат все еще выделены? Также распознается ли поиск в качестве первого ответчика на данный момент?   -  person Ben M    schedule 08.04.2013
comment
@Ben M: он все еще распознается как firstResponder, и поэтому ему все еще выделен его делегат, поскольку он запускает метод делегата.   -  person sj.cleaver    schedule 13.04.2013


Ответы (4)


Хорошо, я понял, в чем проблема. Их первый ответчик уходил в отставку, но клавиатура не исчезала из-за проблемы с фокусом. В модальных представлениях есть поведение по умолчанию, чтобы не убирать клавиатуру (что, по-видимому, не является ошибкой). Таким образом, после возврата из модального представления у него все еще было такое поведение (отказ от первого ответчика, но не отключение клавиатуры). Я решил это, поместив следующий код в оба файла модальных представлений .m:

- (BOOL)disablesAutomaticKeyboardDismissal {
return NO;
}

Это решило это для меня. Затем либо с помощью:

[search resignFirstResponder];

or

[self.view endEditing: YES];

Клавиатура уволится нормально!

person sj.cleaver    schedule 15.04.2013

Вам нужно будет выполнить некоторую отладку с точками останова, чтобы выяснить, почему этот условный оператор не срабатывает. Вы также можете использовать метод endEditing в UIView, чтобы просто отказаться от ответа при каждом нажатии на поиск:

- (void) searchBarSearchButtonClicked:(UISearchBar *)search
        [search endEditing:YES];
}

http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIView_Class/UIView/UIView.html

person ahtierney    schedule 08.04.2013
comment
Я добавил оператор журнала в оператор if else, и после возврата из ViewC3 он утверждает, что он первый ответивший, однако по-прежнему не отклоняет клавиатуру? Я также попробовал ваше предложение [search endEditing: YES], и оно имеет точно такое же поведение. Работает с первого раза, но после возврата из ViewC3 не убирает клавиатуру. - person sj.cleaver; 08.04.2013
comment
поэтому, чтобы уточнить, ваш отладчик показывает, что ваша панель поиска является первым ответчиком, вы поместили точку останова в строке внутри вашего условного выражения, которое отменяет первый ответчик, если это ваша панель поиска, эта строка выполняется и первый ответчик все еще ваша панель поиска? - person ahtierney; 08.04.2013
comment
После отладки я могу подтвердить, что оператор if вводится оба раза (в первый раз и после возврата из ViewC3), указывая, что это первый ответчик, а затем отказывается от первого ответчика. Он действует одинаково оба раза, но по какой-то причине клавиатура все еще не убирается - person sj.cleaver; 08.04.2013

Попробуй....

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
   [mySearchBar resignFirstResponder];
}

Пожалуйста, объявите IBOutlet UISearchBar *mySearchBar; в вашем файле .h
Установите делегата в файле .xib.

Надеюсь, это помогло

person Chirag Pipaliya    schedule 11.04.2013
comment
Вот так все уже было настроено. Панель поиска объявляется как IBOutlet в файле .h, ее делегат задается в методе viewDidLoad файла .m. И метод делегата панели поиска настроен, как показано в моем вопросе. - person sj.cleaver; 11.04.2013
comment
@sj.cleaver: установите делегата в .xib - person Chirag Pipaliya; 12.04.2013
comment
Я попытался установить делегата в раскадровке (не используя .xib), и у меня все еще была точно такая же проблема. - person sj.cleaver; 13.04.2013
comment
@sj.cleaver: установите ‹UISearchBarDelegate, UISearchDisplayDelegate› в файле .h. - person Chirag Pipaliya; 13.04.2013
comment
@sj.cleaver: установите точки останова и проверьте, вызывается ли ваша функция или нет. скажи мне, что случилось. - person Chirag Pipaliya; 13.04.2013
comment
@ Чираг Пипалия: Все настроено, как указано, и я проверил, что функция называется, все нормально. На самом деле он отказывается от первого ответчика, я могу это сказать, потому что клавиатура становится неактивной, при вводе чего-либо это не пишется в строке поиска, но оно не удаляется. Я полагаю, что это может быть какая-то проблема с фокусом, он не перефокусируется после выхода из модального представления, и поэтому клавиатура остается на месте. - person sj.cleaver; 13.04.2013

(Год спустя..)

У меня только что была такая же проблема с моим приложением для iPad.

У меня был UIView «Пожалуйста, зарегистрируйтесь», содержащий несколько UITextFields, которые я выводил на экран. Когда пользователь нажимал кнопку «Закрыть», она исчезала, и я использовал removeFromParentViewController, чтобы избавиться от нее.

[self.pleaseRegisterDlg removeFromParentViewController];

Теперь, когда я запустил этот код на реальном устройстве в режиме отладки из XCode, на этом история закончилась. Все работало нормально. Но когда я создал собственное приложение с помощью этого кода, оно повело себя по-другому.

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

Это не имело смысла, так как в остальной части моего приложения не было UITextFields... у приложения не было причин отображать клавиатуру.

Мое решение состояло в том, чтобы установить «Пожалуйста, зарегистрируйтесь» UIView на ноль после удаления его из родительского представления.

[self.pleaseRegisterDlg removeFromParentViewController];
pleaseRegisterDlg = nil;

По-видимому, наличие UIView, которое на самом деле не связано ни с каким другим UIViews, но содержит UITextFields, иногда достаточно, чтобы сбить iOS с толку и вызвать появление экранной клавиатуры.

(Вздох. Эта одна строчка кода потратила впустую несколько часов моего дня… Усвоенный урок!)

person Mike Gledhill    schedule 16.10.2014