My Application has a modal view controller, including a search bar. When the view comes up, I want the search bar to be focused. I tried [self.searchBar becomeFirstResponder]
in viewDidLoad
, but it didn't work. Later on I put it in viewDidAppear
, it worked. But with this workaround, there is a visible delay. (after the view fully appeared, the keyboard began to appear)
I can ensure both viewDidAppear
and viewDidLoad
have been invoked.
What should I do if I want the search bar to be focused instantly with the view appear?
(I'm using StoryBoard)
Followed the answers, I tried to put the code in viewWillLoad
, but still didn't work. (in viewWillLoad
, self.searchBar.window
is nil)
Possibly it does not work in viewDidLoad, as view does not added into view hierarchy yet. But according to apple documentation becomeFirstResponder should be called only on objects attached to 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.
So, i assume, the best place to achieve necessary behavior is to place call into viewWillAppear
method.
Update.
So, in viewWillAppear controller's view not yet attached to UIWindow... it only notify, that view will be added to view hierarchy
It may be some tricky, but you can make some small delay in 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
});
}
But I believe there is should be a better solution
You should call in viewDidLayoutSubviews(), the code below set textField becomeFirstResponder only at the first time view layout subviews, and it should be.
var isFirstLayout: Bool = true
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if isFirstLayout {
defer { isFirstLayout = false }
textField.becomeFirstResponder()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With