Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableView: How to change cell height dynamically when a button is clicked in it? Swift

I can tell how to do this in objective-c from here, but how can I convert that to swift?

I have a UITableView with custom TableViewCells that has a UIButton called "expandButton". I am trying to figure out how to change the height of that particular cell when the expandButton for that cell is clicked.

Also, when it is clicked again, it should change back to original size. I am not familiar with ObjectiveC so please help me with this in Swift. Thanks a bunch in advance!

Here is what I have so far:

    //Declaration of variables as suggested
        var shouldCellBeExpanded:Bool = false
        var indexOfExpendedCell:NSInteger = -1

Now inside the ViewController. Note: TableViewCell is the name of my custom cell.

    //Inside the ViewController
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    if let cell:TableViewCell = TableViewCell() {

        cell.stopWatch = stopWatchBlocks[indexPath.row]

        cell.expandButton.tag = indexPath.row

        //Adding action to the expand button
        cell.expandButton.addTarget(self, action: "expandButtonAction1:", forControlEvents: UIControlEvents.TouchUpInside)

        return cell

    }

}

Now, the button action method:

    func expandButtonAction1(button:UIButton) {

    button.selected = !button.selected

    if button.selected {

        indexOfExpendedCell = button.tag
        shouldCellBeExpanded = true

        self.TableView.beginUpdates()
        self.TableView.reloadRowsAtIndexPaths([NSIndexPath(forItem: indexOfExpendedCell, inSection: 0)], withRowAnimation: .Automatic)
        self.TableView.endUpdates()

        button.setTitle("x", forState: UIControlState.Selected)
    }

    else if !button.selected {

        indexOfExpendedCell = button.tag
        shouldCellBeExpanded = false

        self.TableView.beginUpdates()
        self.TableView.reloadRowsAtIndexPaths([NSIndexPath(forItem: indexOfExpendedCell, inSection: 0)], withRowAnimation: .Automatic)
        self.TableView.endUpdates()

        button.setTitle("+", forState: UIControlState.Normal)
    }
}

And Finally the HeightForRowAtIndexPath

    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

    if shouldCellBeExpanded && indexPath.row == indexOfExpendedCell {
        return 166.0
    }
    else { return 91.0 }
}

I think I am missing something because the cell does expand when clicked once, but it does not 'shrink' back to 91 ever!

What am I doing wrong here?

like image 924
Vishrut Patel Avatar asked Feb 19 '16 21:02

Vishrut Patel


People also ask

How do I change cell height in Swift?

To change the height of tableView cell in ios dynamically, i.e resizing the cell according to the content available, we'll need to make use of automatic dimension property.

Is it possible to add UITableVIew within a UITableViewCell?

yes it is possible, I added the UITableVIew within the UITableView cell .. :) no need to add tableview cell in xib file - just subclass the UITableviewCell and use the code below, a cell will be created programatically.

What is indexPath in tableView Swift?

indexPath(for:)Returns an index path that represents the row and section of a specified table-view cell.


1 Answers

Try not to use the selected tag as a toggle for a cell state such as this. Once a cell is selected, tapping it again will not deselect. Instead, you can just use the shouldCellBeExpanded flag:

func expandButtonAction1(button:UIButton) {

    shouldCellBeExpanded = !shouldCellBeExpanded
    indexOfExpendedCell = button.tag

    if shouldCellBeExpanded {
        self.TableView.beginUpdates()
        self.TableView.endUpdates()

        button.setTitle("x", forState: UIControlState.Normal)
    }

    else {
        self.TableView.beginUpdates()
        self.TableView.endUpdates()

        button.setTitle("+", forState: UIControlState.Normal)
    }
}

Also, from my experience the reloadRowsAtIndexPath method is unnecessary. Using the beginUpdates() and endUpdates() alone should do the trick unless you need custom animation.

like image 92
jchmilew Avatar answered Nov 14 '22 22:11

jchmilew