Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h2>Solution</h2> <p>In iOS 7, calling <code>becomeFirstResponder</code> on <code>_textView</code> in <code>viewDidLayoutSubviews</code> works.</p> <pre><code>- (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; [_textView becomeFirstResponder]; } </code></pre> <p>Note: Doing it in <code>viewWillLayoutSubviews</code> also works.</p> <h2>Explanation</h2> <p>Read the discussion in the docs for <a href="https://developer.apple.com/library/ios/documentation/uikit/reference/UIResponder_Class/Reference/Reference.html#//apple_ref/occ/instm/UIResponder/becomeFirstResponder" rel="noreferrer">becomeFirstResponder</a>.</p> <blockquote> <p>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 <code>window</code> property holds a <code>UIWindow</code> object, it has been installed in a view hierarchy; if it returns <code>nil</code>, the view is detached from any hierarchy.</p> </blockquote> <p>When using a navigation controller to push your custom view controller onscreen, <code>self.view.window</code> is still <code>nil</code> by the time either <code>viewDidLoad</code> or <code>viewWillAppear:</code> is called. So, <code>_textView.window</code> is also <code>nil</code> in the same methods, since <code>_textView</code> is a subview of <code>self.view</code>, i.e., they're both in the same window. No matter how you present your custom view controller, <code>self.view.window</code> (and thus <code>_textView.window</code>) is also <code>nil</code> in <code>initWithNibName:bundle:</code>. <code>self.view.window</code> is set by the time <code>viewDidAppear:</code> is called, but that's too late because by that time, the navigation controller has already completed the animation of pushing the view onscreen.</p> <p><code>self.view.window</code> is also set by the time either <code>viewWillLayoutSubviews</code> or <code>viewDidLayoutSubviews</code> is called and these methods are called before the push animation of the navigation controller begins. So, that's why it works when you do it in either of those methods.</p> <p>Unfortunately, <code>viewWillLayoutSubviews</code> and <code>viewDidLayoutSubviews</code> get called a lot more than just on the initial navigation controller push. But, <code>navigationController:willShowViewController:</code> and <code>willMoveToParentViewController:</code> get called too soon (after <code>viewDidLoad</code> but before <code>self.view.window</code> is set) and <code>navigationController:didShowViewController:</code> and <code>didMoveToParentViewController:</code> get called too late (after the push animation).</p> <p>The only other way I can think of doing it is to somehow observe the <code>window</code> property of <code>_textView</code> so that you get notified when it changes, but I'm not sure how to do that since <code>window</code> is <code>readonly</code>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload