title: UITableView - Scroll to bottom before viewDidAppear
body: <p>In case it's not obvious by the title, what I want should be simple, for the <code>tableView</code> to start scrolled all the way to the bottom when the users first sees it (<strong>before he sees it, and without animations</strong>).</p>
  
  <p>So, I know that this has been answered a few times, but none of those solutions seem to work right now.
  To give some context, I'm using Swift, autolayout and latest version of iOS as of today.</p>
  
  <p><strong>Constraints</strong></p>
  
  <p>There are some things I need to support:</p>
  
  <ol>
  <li>load it before user sees it (without animations, obviously).</li>
  <li>dynamic cell heights, i.e., their height is determined by a UILabel (like a messaging app - using autolayout in storyboard).</li>
  <li>My <code>UITableView</code> is inside a <code>UIScrollView</code> (<code>UIScrollView</code> scrolls horizontally and <code>UITableView</code> scrolls vertically).</li>
  <li>The <code>UITableView</code> is in a <code>childViewController</code>, i.e., I add it to the main <code>UIViewController</code> (which, for some reason, makes <code>viewWillAppear</code> not get called - <code>viewDidAppear</code> is still called).</li>
  </ol>
  
  <p>I'll make a summary of what I tried:</p>
  
  <p><strong>As for implementations:</strong></p>
  
  <ol>
  <li><p><code>tableView.contentOffset = CGPoint(x: 0, y: CGFloat.max</code></p></li>
  <li><p><code>tableView.scrollToRowAtIndexPath(indexPathForLastItem, atScrollPosition: .Bottom, animated: false)</code></p></li>
  <li><p></p></li>
  </ol>
  
  <pre><code>
      var contentOffset = tableView.contentOffset
      contentOffset.y = tableView.contentSize.height - tableView.bounds.size.height
      tableView.setContentOffset(contentOffset, animated: false)
  
  </code></pre>
  
  <ol start="4">
  <li></li>
  </ol>
  
  <pre><code>
      dispatch_async(dispatch_get_main_queue(), {
          // tried option 1., 2. and 3. here
      })
  
  </code></pre>
  
  <p><strong>As for places I've tried to call those implementations:</strong></p>
  
  <ol>
  <li><code>viewDidLoad</code></li>
  <li><code>viewWillAppear</code></li>
  <li><code>viewDidLayoutSubviews</code> (only the first time it's called, I use a property to track that)</li>
  <li><code>viewDidAppear</code> (even though this wouldn't give me what I want)</li>
  <li>On my model's <code>didSet</code></li>
  </ol>
  
  <p>Before those I always called <code>tableView.reloadData</code></p>
  
  <p><strong>What I DON'T want to do:</strong></p>
  
  <p><code>tableView.transform = CGAffineTransformMakeScale(1, -1)</code></p>
  
  <p>+</p>
  
  <p><code>cell.transform = CGAffineTransformMakeScale(1, -1)</code></p>
  
  <p>(I'm assuming that if you think of suggesting this solution, it's because you know the hack I'm talking about. If you don't, then you won't be suggesting this, so you don't need to understand how it works)</p>
  
  <p>One of the reasons why I don't want this one is because now I can't scroll to the top...</p>
  
  <p><strong>Problems I've noticed:</strong></p>
  
  <ol>
  <li>The <code>tableView</code>'s <code>contentSize</code> (as a <code>UIScrollView</code> subclass) changes when you scroll for the first time after it appeared. Yes, I meant <code>contentSize</code>, not <code>contentOffset</code>, and it changes more than once while you scroll. After you've scrolled through the entire <code>tableView</code> once, it doesn't change anymore.</li>
  <li>Some people are saying it works for fewer cells (and to be honest, it was working for me at some point), so try it with at least 20 items.</li>
  <li><code>viewWillAppear</code> doesn't get called, but <code>viewDidAppear</code> does.</li>
  </ol>
  
  <p>Any solutions (except for the one I mentioned I don't want) would be very much appreciated. Even hacky ones, as long as they don't break other stuff.</p>
  
  <p>Just as a side note, <code>scrollToRowAtIndexPath...</code> does not scale, i.e., it is too slow if you have, say, 2000 items. So Ideally I'd prefer a solution that scales.</p>
  
  <p><strong>EDITS AFTER ANSWERS:</strong></p>
  
  <ol>
  <li><p>After @bsmith11's answer I tried:</p>
  
  <pre><code>private var called = false
  override func viewDidLayoutSubviews() {
      super.viewDidLayoutSubviews()
  
      if !called {
          dispatch_async(dispatch_get_main_queue(), {
              self.tableView.setContentOffset(CGPoint(x: 0, y: self.tableView.bounds.height), animated: false)
          })
          called = true
      }
  }
  </code></pre>
  
  <p>And it didn't work.</p></li>
  </ol>