YichenBman YichenBman - 6 months ago 14
Swift Question

Static TableViewCells Adjust Height, Fill View Height

My app requires a few things that UITableViews make a lot simpler to do. I'm running into this issue though: I want the bottom cell to always be at the bottom of the view controller, and I want all the cells to dynamically adjust their height so every single cell fits inside of the viewcontroller, no scrolling needed to see more cells.

Essentially I want 3 or 4 big tableViewCells that all dynamically change height depending on which device is being used. Caveat: all these cells need to be different heights. Any ideas?

Answer

Expanding on @Vig's comment:

You didn't specify how the cell heights were being determined, so I assumed they weren't normalised between 0 and 1.

Therefore, in your UITableViewController you need the following variables:

For my example I'm using absoluteCellHeights as the data to determine the cell heights, this would need to change for your purposes.

var absoluteCellHeights: [CGFloat] = [50, 40, 20, 10] {
    didSet {
        tableView.reloadData()
    }
}

normalisedCellHeights takes the absoluteCellHeights and scales them to be in the interval 0 to 1. However, in the case absoluteCellHeights is just full of zeros nil will be returned.

var normalisedCellHeights: [CGFloat]? {
    let totalHeight = absoluteCellHeights.reduce(0, combine: +)
    let normalisedHeights: [CGFloat]? = totalHeight <= 0 ? nil : absoluteCellHeights.map { $0 / totalHeight }

    return normalisedHeights
}

Now in heightForRowAtIndexPath you can do:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    //  Swift 1.2, which is why I'm using 'let' here.
    let height: CGFloat

    //  It is assumed there is only one section.
    if let normalisedHeight = self.normalisedCellHeights?[indexPath.row] {
        height = normalisedHeight * tableView.frame.height
    } else {
        height = 50.0 // Just a random value.
    }

    return height
}

Finally, because you don't want the table to scroll you need to add tableView.scrollEnabled = false when you're configuring your table view. Possibly IB if you're using Storyboards?

The final result:

enter image description here