GetFirstResponder работает в viewDidAppear, но не работает в viewDidLoad
В моем приложении есть модальный контроллер просмотра, включая панель поиска. Когда появится представление, я хочу, чтобы панель поиска была сфокусирована. Я пробовал [self.searchBar becomeFirstResponder]
в viewDidLoad
, но это не сработало. Позже я положил его в viewDidAppear
, он сработал. Но с этим обходным путем существует заметная задержка. (после того, как представление полностью появилось, клавиатура начала появляться)
Я могу гарантировать, что будут вызваны как viewDidAppear
, так и viewDidLoad
.
Что делать, если я хочу, чтобы панель поиска мгновенно сфокусировалась с представлением?
(Я использую StoryBoard)
Следуя ответам, я попытался поместить код в viewWillLoad
, но все равно не работал. (в viewWillLoad
, self.searchBar.window
равно nil)
Ответы
Ответ 1
Возможно, он не работает в viewDidLoad, поскольку представление еще не добавлено в иерархию представлений. Но согласно документации на яблоко beFirstResponder следует вызывать только на объектах, прикрепленных к UIWindow:
However, you should only call it on that view if it is part of a view hierarchy.
If the view’s window property holds a UIWindow object, it has been installed
in a view hierarchy; if it returns nil, the view is detached from any hierarchy.
Итак, я полагаю, лучшее место для достижения необходимого поведения - это поместить вызов в метод viewWillAppear
.
Обновить.
Итак, в представлении контроллера viewWillAppear еще не подключен к UIWindow... он только уведомляет, что этот вид будет добавлен для просмотра иерархии
Это может быть несколько сложнее, но вы можете сделать небольшую задержку в viewWillAppear:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
double delayInSeconds = 0.05;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^{
make first responder here
});
}
Но я считаю, что должно быть лучшее решение
Ответ 2
все объекты IBOutlet загружаются в viewDidLoad, если вы вызываете метод в viewDidLoad, тогда это действие не выполняется, потому что перед тем, как объекты загружаются, мы не можем ничего сделать, чтобы почему-то писать этот код в
-(void)viewWillAppear:(BOOL)animated{
//write here
}
тогда он отлично работает.
Ответ 3
Создание текстового поля/просмотра первого ответчика должно выполняться после всех анимаций UIViewController, которые происходят, когда просмотр загружается и отображается. Поэтому лучшим местом является viewDidAppear.
Ответ 4
Это поможет:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
dispatch_async(dispatch_get_main_queue(), ^{
[self.quantifyTextField becomeFirstResponder];
});
}
Ответ 5
Напишите viewWillAppear
instad viewDidAppear/viewDidLoad
.
Так как метод viewWillAppear
является вызовом во время представления, будет отображаться (в процессе), для получения дополнительной информации about viewWillAppear
прочитать этот официальный документ.
- (void)viewWillAppear:(BOOL)animated
{
[self.searchBar becomeFirstResponder];
[super viewWillAppear:animated];
}
Ответ 6
Я знаю, что это немного старый поток, но я думаю, что он может помочь кому-то, кто сталкивается с проблемой клавиатуры при добавлении этого кода.
Не забудьте установить делегат текстового поля в nil в viewWillDisappear, иначе клавиатура больше не будет отображаться, если вы поместите/отклоните контроллер вида, не закрывая клавиатуру.