UIView.animateWithDuration does not work within a UITableviewCell

2.3k views Asked by At

I have a UITableviewCell subclass that contains a UIButton that is placed off-screen (right) with a Autolayout Horizontal Space Constraint to it's superview of -312.

Now I want to animate this constraint to a value of -8 when the the cell is selected.

I have created a outlet for this constraint in the cell class and I tried to animate this constraint with the following code:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let cell = tableView.dequeueReusableCellWithIdentifier("VariationsTableViewCell", forIndexPath: indexPath) as! VariationsCell

    UIView.animateWithDuration(1.0, delay: 0.0, options: .CurveEaseOut, animations: {

        cell.buttonRightSideConstraint.constant = -8

        }, completion: { finished in
            println("Button revealed!")
    })

} 

This unfortunately does not work. If I reload the tableview with .reloadData() the button is shown, which tells me that that the Autolayout constraint gets updated but the animation does not get triggered.

1

There are 1 answers

10
Eendje On BEST ANSWER

When animating with auto layout, you have to use layoutIfNeeded to animate the changes in the constraints.

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("VariationsTableViewCell", forIndexPath: indexPath) as! VariationsCell

    UIView.animateWithDuration(1.0, delay: 0.0, options: .CurveEaseOut) {
         cell.layoutIfNeeded()
    }

    return cell
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let cell = tableView.dequeueReusableCellWithIdentifier("VariationsTableViewCell", forIndexPath: indexPath) as! VariationsCell

    cell.buttonRightSideConstraint.constant = -8

    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
}