Пользовательские проблемы UITableViewCell + UITextField - PullRequest
2 голосов
/ 23 декабря 2011

У меня проблема, которую я не могу понять.

Что у меня настроено:

  1. Пользовательский UITableViewCell, в котором есть несколько текстовых полей.Аналогично настройке Apple при добавлении нового адреса для кого-то в контактах.
  2. Таблица с пользовательской ячейкой представляется как модальное представление.Это табличное представление также имеет другие ячейки, которые являются общими (то есть не пользовательская ячейка, указанная в 1.).
  3. Представленный модальный вид имеет панель инструментов вверху, которая содержит кнопку «Готово».Когда нажата кнопка «Готово», модальное представление отправляет вызов своему делегату и отклоняет его.

Проблема, с которой я столкнулся: Когда пользователь выбирает UITextField и начинает редактировать UIKeyboard, он представлен (очевидно, верно?).Если клавиатура открыта, и пользователь выбирает «готово» на панели инструментов (как указано в 3.), приложение вылетает, потому что родительское представление пытается отклонить модальное представление (модальное представление, содержащее клавиатуру), пока клавиатура открыта,

Высокий уровень, похоже, он должен работать следующим образом:

Пользователь нажимает кнопку «Готово» на панели инструментов -> проверить, открыта ли UIKeyboard -> если открыт, закрыть, иначе закрыть модальное представление

Но это было не так просто.

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

Любые предложения будут очень признательны.

Редактировать

Вот журнал сбоев:

2011-12-22 16:03:09.021 Renshaw[2308:5f43] bool _WebTryThreadLock(bool), 0xad7a9e0: Tried     to obtain the web lock from a thread other than the main thread or the web thread. This may be     a result of calling to UIKit from a secondary thread. Crashing now...
1   _ZL17_WebTryThreadLockb
2   WebThreadLock
3   -[UITextRangeImpl isEmpty]
4   -[UITextRange(UITextSelectionAdditions) _isCaret]
5   -[UITextSelectionView setCaretBlinks:]
6   -[UIKeyboardImpl setCaretBlinks:]
7   -[UIKeyboardImpl setDelegate:force:]
8   -[UIPeripheralHost(UIKitInternal) _reloadInputViewsForResponder:]
9   -[UIResponder _finishResignFirstResponder]
10  -[UIResponder resignFirstResponder]
11  -[UITextField resignFirstResponder]
12  -[UIView(UITextField) endEditing:]
13  -[UIWindowController _prepareKeyboardForTransition:fromView:]
14  -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:]
15  -[UIViewController _dismissViewControllerWithTransition:from:completion:]
16  -[UIViewController dismissViewControllerWithTransition:completion:]
17  -[UIViewController dismissViewControllerWithTransition:completion:]
18  -[ListingsViewController postSearch:allObjects:constrainedList:]
19  -[FilterViewController searchObjects]
20  -[NSObject performSelector:withObject:]
21  -[MBProgressHUD launchExecution]
22  -[NSThread main]
23  __NSThread__main__
24  _pthread_start
25  thread_start
[Switching to process 10499 thread 0x2903]
[Switching to process 10499 thread 0x2903]

Ответы [ 5 ]

5 голосов
/ 23 декабря 2011

Подсказка находится в следе стека:

Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...

Вы вызываете метод UIKit из вторичного потока. Вы должны делать что-то не в главном потоке, например, вызывать resignFirstResponder. Смотрите здесь для получения дополнительной информации об этом:

Обновление:

Оказывается, решение было использовать что-то вроде:

dispatch_async(dispatch_get_main_queue(), ^{ <code_here> });

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

1 голос
/ 23 декабря 2011

Поместите это выше вашего @ implementation

static UITextField *currentlySelectedTextField = nil;

И переопределить эти методы

- (void)viewWillDisappear {
  [super viewWillDisappear];
  [currentlySelectedTextField resignFirstResponder];
}

- (void)textFieldDidBeginEditing:(UITextField *)textField {
  currentlySelectedTextField = textField;
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
  currentlySelectedTextField = nil;
}

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

0 голосов
/ 11 июня 2012

У меня была похожая проблема, но не в textFieldShouldReturn, а скорее в textFieldDidBeginEditing.

Проблема заключалась в том, что textField был добавлен в модальном представлении, но в базовом представлении также было текстовое поле.Базовое textField было создано в Интерфейсном Разработчике и для этого было выделено и установлено как First Responder до того, как модальное представление было даже на экране.Это привело к той же ошибке, что и выше.

Это легко исправить, НЕ добавляя базовый textField в IB.Я добавил это программно позже, когда это было необходимо в базовом представлении.

Простое исправление, трудно найти проблему; -)

Приветствия Ник

0 голосов
/ 16 марта 2012

Я видел _webthreadlockfromanythread сбой при необходимости нажать UIViewController после проверки некоторых значений в textFieldShouldReturn.

Если вам нужно использовать textFieldShouldReturn, вот что работает:

  1. Если textFieldShouldReturn вернет YES, вам также нужно будет позвонить resignFirstResponder на textfield
  2. Это, в свою очередь, вызовет textFieldDidEndEditing: и запустит анимацию, чтобы убрать клавиатуру.

Вызвано исключение _webthreadlockfromanythread, поскольку мое приложение выдвигало контроллер представления до того, как клавиатура была полностью закрыта.

Решение состоит в том, чтобы добавить наблюдателя для UIKeyboardDidHideNotification и метод, который получает уведомление, чтобы подтолкнуть ваш контроллер представления. Удачи!

0 голосов
/ 23 декабря 2011

Как насчет отключения кнопки «Готово», когда текстовое поле становится активным?

Просто сделайте: doneButton.enabled = NO;, когда текстовое поле becomesFirstResponder, затем включите кнопку Готово, когда клавиатура отклонена (в textFieldShouldReturn:(UITextField*)textField).

...