emelagumat
emelagumat

Reputation: 311

Conditionally change height of cells in UITableView

I am making a form in a tableview.

Let's say I have 4 different types of cells, each being a question with different kind of answers

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if sortedFixedContentType.count != 0 {
        let item = sortedFixedContentType[indexPath.row]

        switch item.typeId {
        case "1":
            let cell = tableView.dequeueReusableCell(withIdentifier: "FirstCell", for: indexPath) as! FirstCell
            return cell;

        case "2":
            let cell = tableView.dequeueReusableCell(withIdentifier: "SecondCell", for: indexPath) as! SecondCell
            cell.customDelegate = self
            return cell;
        case "3":
            let cell = tableView.dequeueReusableCell(withIdentifier: "ThirdCell", for: indexPath) as! ThirdCell
            cell.commentsTextView.delegate = self
            return cell;

        case "4":
            let cell = tableView.dequeueReusableCell(withIdentifier: "FourthCell", for: indexPath) as! FourthCell
            return cell;

}

When the tableView is loaded I want to show only first cell, and depending on the answer different cells will be shown.

For example:

FirstCell can be answered with A, B, or C,

If I answer A SecondCell will be shown with answers X and Y.

If X is the answers ThirdCell will be shown (which has no options but a TextField), and when completed FourthCell will be shown

But if in FirstCell the answer is B or C only FourthCell will be directly shown.

At the moment I was doing it by changing the height of the rows in heightForRowAt, although I think there must be an easier way. However I'm finding a problem:

If I get to the textField in ThirdCell and then I change my first answer, SecondCell is hidden but ThirdCell is not, as the condition to it was the second answer and it's already made, so I thought on setting the height of each row as condition to, but I don't know how to do it.

So I have two main questions:

Thanks in advance!

Upvotes: 0

Views: 296

Answers (2)

Dave Levy
Dave Levy

Reputation: 1192

What I usually like to do is monitor a variable and when the variable is updated adjust the height of the cell. Make sure that your variable has this didSet code assigned to it so your tableview updates the height when the variable changes.

var selectedRow: Int = 999 {
        didSet {
            tableView.beginUpdates()
            tableView.endUpdates()
        }
    }

And then, just like you have done I affect the height of the row inside of the heightForRow function.

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if indexPath.row == selectedRow {  //assign the selected row when touched
            let thisCell = tableView.cellForRow(at: indexPath)

            if let thisHeight = thisCell?.bounds.height {
                print("Bam we got a HEIGHT!!")
                return thisHeight + 50

            }
        }
    return 60 //return a default value in case the cell height is not available
}

Upvotes: 0

Tom Pearson
Tom Pearson

Reputation: 384

I think the conventional method is to not modify the height but manipulate the data source (the number of rows in section etc.) to show/hide the appropriate cells.

You should update the data source appropriately after an event and then immediately after you can use func insertRows(at indexPaths: [IndexPath], with animation: UITableView.RowAnimation) and tableView.deleteRowsAt(at indexPaths: [IndexPath], with animation: UITableView.RowAnimation) to insert/delete cells in the tableView

This documentation might help: https://developer.apple.com/documentation/uikit/uitableview/1614879-insertrows

Upvotes: 1

Related Questions