Show and hide different height tableView cells in iOS (swift)

If you have a tableView with predefined cells (rows) of different height and you want to dynamically hide some of them.

iOS tableView different heights cells

In my case I want to hide Quantity row when type is set as Second. It could be done by setting this cell height to 0. Like this:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
  if type.selectedSegmentIndex == 1 && indexPath.row == 3 {
    return 0.0
  }
  
  return 72.0
}

But the problem here is that heightForRowAtIndexPath will be called for all the rows and it seems that there is no simple way to update the height to only one cell. You’ll have to update all cells. Which in our case is not a problem because we know all our cells beforehand. So we can update our code to:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
  if indexPath.row == 0 {
    return 150.0
  }
  
  if type.selectedSegmentIndex == 1 && indexPath.row == 3 {
    return 0.0
  }
  
  return 72.0
}

As you can see there are almost no changes from previous code. We only updated the height of first cell (index 0) that is higher then others. But if we just click on type control then nothing changes. In order to fix that we have to tell the renderer that we want to update how cells look like. A solution is to call tableView.reloadData() whenever Type‘s value changes (take care as it is not an optimal solution):

@IBAction func changeType(sender: UISegmentedControl) {
  self.tableView.reloadData()
}

But this may result in cells overlap like this
iOS tableView different heights cells overlap

In order to fix that we can additionally hide the cell when Type value changes:

@IBAction func changeType(sender: UISegmentedControl) {
  var cell3Index = NSIndexPath.init(forRow: 3, inSection: 0)
  var quantityCell = self.tableView.cellForRowAtIndexPath(cell3Index)

  if sender.selectedSegmentIndex == 1 {
    quantityCell?.hidden = true
  } else {
    quantityCell?.hidden = false
  }

  self.tableView.reloadData()
}

That’s it. Now our tableView looks as intended.

iOS tableView different heights cells hidden