swiftuitableviewtableviewrow-height

Change only one specific tableView row height


I'm looking for a way to change a specific row in my tableView.

I'm using a Notification to check when I do an action in my cell. According to the answer, my goal is to display the next row.

By default, my cell have this property.

if (indexPath.row == 5){
    tableView.rowHeight = 0.0
}

if (indexPath.row == 6){
    tableView.rowHeight = 0.0
}

return cell

My goal when I'm in my notification is to change the row height value for the fifth row.

Thank you for your help


Solution

  • You could use a Set<IndexPath> and your tableView delegate methods to achieve this.

    Say you have a set of selected index paths selectedIndexPaths and heights largeHeight and normalHeight. Your heightForRow func could look like this:

    func tableView(_ tableView: UITableView, heigthForRowAt indexPath: IndexPath) -> CGFloat {
        guard !selectedIndexPaths.contains(indexPath) else {
            return largeHeight
        }
    
        return normalHeight
    }
    

    Then you could change the height dynamically the following way:

    /// Convenience method for selecting an index path
    func select(indexPath: IndexPath, completion: ((Bool) -> Void)? = nil){
        selectedIndexPaths.insert(indexPath)
        tableView.performBatchUpdates({
            self.tableView.reloadRows(at: [indexPath], with: .none)
        }, completion: completion)
    }
    

    In your tableView delegate, you could call this method in didSelect:

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        select(indexPath: indexPath)
    }
    

    Do the same if you have a method responding to your notification (assuming you placed your indexPath in your notification's userInfo, under the key "indexPathKey"):

    func notifiedShouldEnlargeRow(aNotification: Notification) {
        guard let indexPath = aNotification.userInfo["indexPathKey"] as? IndexPath else { return }
        select(indexPath: indexPath)
    }
    

    For reference, look at performBatchUpdates(_:completion) and reloadRows(at:with:).