UITextField теряет firstResponder после появления представления

У меня есть UIPageViewController. На одной странице есть одна кнопка, а на другой странице есть UITextField с кнопкой. Когда страница прокручивается до представления с полем, я бы хотел, чтобы оно becomeFirstResponder и открывало клавиатуру. Вот что происходит:

  • Я вызываю метод viewDidAppear [self.locationQuery becomeFirstResponder] ViewController. Но он никогда не открывает клавиатуру.

  • Я делаю то же самое в viewWillAppear, и он ненадолго появляется, но затем быстро исчезает.

  • Если я нахожусь на странице с текстовым полем и частично вытягиваю страницу и отпускаю ее (без смены страниц), self.locationQuery получает фокус просто отлично.

Похоже, что-то еще захватывает статус firstResponder из поля, но я понятия не имею, что и почему это происходит только при изменении страницы (а не раскрывается после неудачного перелистывания страницы). Есть идеи?

Обновить

Я создал способ обхода представлений, чтобы увидеть, действительно ли какие-либо другие представления принимают firstResponder (из ответа на этот вопрос: Получить текущего первого ответчика без использования частного API). Результаты:

  • Когда я явно даю первому ответчику текстовое поле, метод сообщает, что он имеет статус первого ответившего.

  • Когда я этого не делаю, он возвращает null.

Теперь я еще больше запутался.


person dclowd9901    schedule 09.01.2014    source источник


Ответы (2)


Я действительно не понимаю природу того, что вызвало мою проблему, но я смог ее исправить, заключив вызов в асинхронную отправку в viewDidAppear:

dispatch_async(dispatch_get_main_queue(), ^{
    MapManualViewController *strongSelf = weakSelf;
    [strongSelf.locationQuery becomeFirstResponder];
});
person dclowd9901    schedule 12.01.2014
comment
была такая же проблема, это исправило, спасибо. Я тоже не совсем понимаю это, но я думаю, поскольку мы касаемся пользовательского интерфейса, когда появляется клавиатура, имеет смысл получить основную очередь - person MadeByDouglas; 21.01.2016
comment
Я попытался установить точку останова в методе, запускаемом UIKeyboardWillHideNotification, и посмотреть на трассировку стека. Похоже, это вызвано деталями реализации UIPageViewController, где он меняет представление вашего контроллера представления между двумя внутренними представлениями прокрутки в конце анимации. Затем UITextView отказывается от функции первого ответчика, потому что он ненадолго удаляется из иерархии представлений. Похоже, ваше решение просто откладывает становление первым ответчиком до следующего цикла запуска. - person Adam Swinden; 05.10.2016

Этот украл несколько часов из моей жизни. Вот реализация Swift 3.x.

DispatchQueue.main.async(execute: {() -> Void in
    let strongSelf: MapManualViewController = self
    strongSelf. textField.becomeFirstResponder()
})

Я тоже поставил его в viewDidAppear

person Arel    schedule 21.04.2017
comment
Здесь вам не нужен strongSelf, и его можно сократить до DispatchQueue.main.async() { self.textField.becomeFirstResoonder() }. - person chadbag; 27.10.2017