title: Updating contentSize of a UIScrollView based UITableView height
body: <p>I'm having some trouble updating the size of my <code>UIScrollView</code> to adjust to my <code>UITableView</code> height changes.</p>
  
  <p>my <code>UITableView</code> is not scrollable. Instead the size of my view changes based on the amount of cells in my <code>UITableView</code>.</p>
  
  <p>I have one <code>UIViewController</code> That I use to load 3 different datasets. (which requires to update my UITableView to accommodate different amounts of data often)</p>
  
  <p>So when I load the first dataset it works fine.</p>
  
  <p>However, if I load a new one after that, with a different amount of cells. My contentSize of my UIScrollView is now wrong. (it keeps the size from whatever the previous dataset was).</p>
  
  <p>Here's an example:</p>
  
  <p><img src="https://i.stack.imgur.com/pPzL0.png" alt="enter image description here"></p>
  
  <p>Where I went from a dataset that had more cells. To one with less. You can see I'm able to scroll down much further than I should be able to. (The end of the contentSize should be stopping 16 points after the white area.</p>
  
  <p>After attempting to fix this issue for a while, I did manage to get something working. I get my data from an API, which sometimes take a long time to fetch. However, when It's done updating all the data in my tableView I was able to fix the contentsize to what I want with the following line of code:</p>
  
  <pre><code>self.scrollView.contentSize = CGSize(width:self.view.bounds.width, height: self.contentView.frame.height)
  </code></pre>
  
  <p>First action after that worked, was to put that earlier. (Before I attempt to update the data.) But unfortunately that doesn't seem to do anything at all.</p>
  
  <p>So how can I as soon as I reload my UITableView with the data from CoreData (before attempting to fetch new data) set my contentSize correctly?</p>
  
  <p>Here is the function that loads the data. (This happens instantly. It's the end of this function after the reload, I need to fix the contentsize.</p>
  
  <pre><code>func loadPortfolio() {
  
      println("----- Loading Portfolio Data -----")
      // Set the managedContext again.
      managedContext = appDelegate.managedObjectContext!
  
      // Check what API to get the data from
      if Formula == 1 {
          formulaEntity = "PortfolioBasic"
          println("Setting Entity: \(formulaEntity)")
          formulaAPI = NSURL(string: "http://api.com/json/monthly_entry.json")
      } else if Formula == 2 {
          formulaEntity = "PortfolioPremium"
          formulaAPI = NSURL(string: "http://api.com/json/monthly_proff.json")
          println("Setting Entity: \(formulaEntity)")
      } else if Formula == 3 {
          formulaEntity = "PortfolioBusiness"
          println("Setting Entity: \(formulaEntity)")
          formulaAPI = NSURL(string: "http://api.com/json/monthly_fund.json")
      } else {
          println("Errror - Formula out of range.")
      }
  
      // Delete all the current objects in the dataset
      let fetchRequest = NSFetchRequest(entityName: formulaEntity)
      let a = managedContext.executeFetchRequest(fetchRequest, error: nil) as! [NSManagedObject]
      stocks.removeAll(keepCapacity: false)
      for mo in a {
          stocks.append(mo)
      }
  
      // Saving the now empty context.
      managedContext.save(nil)
  
  
      // Setting the first cell to be white
      cellAlteration = 0
  
      // Reload the tableview with the new data.
      self.pHoldingsTable.reloadData()
  
      tableHeight.constant = CGFloat(stocks.count*50)
  
  
      // This doesn't work here for some reason?
      self.scrollView.contentSize = CGSize(width:self.view.bounds.width, height: self.contentView.frame.height)
  
  println("Finished loading portfolio")
  
  
      self.view.hideLoading()
  
      dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.value), 0)) {
          self.updatePortfolio()
      }
  
  }
  </code></pre>
  
  <p>I also tried putting the scrollView related line before the constraint update, but that didn't work either.</p>
  
  <p>However. Below is my updatePortfolio() function which uses the exact same line of code, and works fine. Once this finishes running my contentView is being set to the correct size.</p>
  
  <pre><code>func updatePortfolio() {
      println("Updating Portfolio")
      if Reachability.isConnectedToNetwork() == false {
          println("ERROR: - No Internet Connection")
      } else {
          // Delete all the current objects in the dataset
          let fetchRequest = NSFetchRequest(entityName: formulaEntity)
          let a = managedContext.executeFetchRequest(fetchRequest, error: nil) as! [NSManagedObject]
          for mo in a {
              managedContext.deleteObject(mo)
          }
          // Removing them from the array
          stocks.removeAll(keepCapacity: false)
          // Saving the now empty context.
          managedContext.save(nil)
  
          // Set up a fetch request for the API data
          let entity =  NSEntityDescription.entityForName(formulaEntity, inManagedObjectContext:managedContext)
          var request = NSURLRequest(URL: formulaAPI!)
          var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)
          var formula = JSON(data: data!)
  
          // Loop through the api data.
          for (index: String, portfolio: JSON) in formula["portfolio"] {
  
              // Save the data into temporary variables
              stockName = portfolio["name"].stringValue.lowercaseString.capitalizedString
              ticker = portfolio["ticker"].stringValue
              purchasePrice = portfolio["purchase_price"].floatValue
              weight = portfolio["percentage_weight"].floatValue
  
  
              // Set up CoreData for inserting a new object.
              let stock = NSManagedObject(entity: entity!,insertIntoManagedObjectContext:managedContext)
  
              // Save the temporary variables into coreData
              stock.setValue(stockName, forKey: "name")
              stock.setValue(ticker, forKey: "ticker")
              stock.setValue(action, forKey: "action")
              stock.setValue(purchasePrice, forKey: "purchasePrice")
              stock.setValue(weight, forKey: "weight")
  
              // Doing a bunch of API calls here. Irrelevant to the question and took up a ton of code, so skipped it to make it more readable.
  
  
              // This can simply be set, because it will be 0 if not found.
              stock.setValue(lastPrice, forKey: "lastPrice")
  
              // Error handling
              var error: NSError?
              if !managedContext.save(&amp;error) {
                  println("Could not save \(error), \(error?.userInfo)")
              }
              // Append the object to the array. Which fills the UITableView
              stocks.append(stock)
          }
  
          NSOperationQueue.mainQueue().addOperationWithBlock({ () -&gt; Void in
              // Setting the first cell to be white
              cellAlteration = 0
              self.tableHeight.constant = CGFloat(self.stocks.count*50)
              self.pHoldingsTable.reloadData()
              self.scrollView.contentSize = CGSize(width:self.view.bounds.width, height: self.contentView.frame.height)
              println("Finished Updating Portfolio")
          })
      }
  }
  </code></pre>
  
  <p>I also tried putting the tableHeight constraint above the reload like It is in the update function. But it didn't make a difference.</p>
  
  <p>Here's how my UIScrollView is set up:</p>
  
  <pre><code>    override func viewDidLayoutSubviews() {
      super.viewDidLayoutSubviews()
      scrollView.frame = view.bounds
      scrollView.contentSize = CGSize(width:self.view.bounds.width, height: contentView.frame.height)
  }
  </code></pre>
  
  <p>This always gets the correct size the first time. But because this function is not called when the tableView changes. It does not update the contentSize automatically.</p>
  
  <p>my contentView.frame.height changes depending the amount of cells in the UITableView. It's not a fixed height. (I never want my UITableView itself to scroll inside it's box)</p>
  
  <p>Also in case my issues are constraint related and not in my function, I'm doing it all programatically. I'm not using storyboards or XIB files.</p>
  
  <p>Any help would be greatly appreciated!</p>