Why is becomeFirstResponder not working?

Ravi picture Ravi · Nov 26, 2013 · Viewed 15.6k times · Source

I added a modal using AGWindowView. Inside the modal view (built using IB), there is a textfield. The textfield has been connected to an outlet.

This doesn't work:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self.placesTextField becomeFirstResponder];
}

The call to becomeFirstResponder doesn't work and the keyboard doesn't show up.

This works:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self.placesTextField performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0];
}

However, if I manually send a message using performSelector:withObject:afterDelay it works. Why is this method not being determined until runtime?

Answer

βhargavḯ picture βhargavḯ · Nov 26, 2013

Seems somehow in iOS7, view/object is not attached in view hierarchy / window yet. So calling method over object fails. If we put some delay and it is working that means at that moment objects are attached to window.

As per Apple,

A responder object only becomes the first responder if the current responder can resign first-responder status (canResignFirstResponder) and the new responder can become first responder.

You may call this method to make a responder object such as a view the first responder. 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.

For more details see UIResponder Class Reference.