I've been playing around trying to animate contents of my tableviewcell when it is selected, but i'm having issues. I had read some places that you cannot run animatewithduration within didSelectRowAtIndexPath or at least it doesn't animate if you do. It seems to be the case with the code I have below, the view moves but doesn't animate.
I have tried incorporating logic into willDisplayCell to monitor for the selection but to no avail, and so I would love it if someone is able to find the right solution for me because the answer is seemingly not available, despite a lot of searching:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let currentCellDescriptor = getCellDescriptorForIndexPath(indexPath)
let cell = tableView.dequeueReusableCellWithIdentifier(currentCellDescriptor["cellIdentifier"] as! String, forIndexPath: indexPath) as! CustomCell
let indexOfTappedRow = visibleRowsPerSection[indexPath.section][indexPath.row]
if cellDescriptors[indexPath.section][indexOfTappedRow]["isExpandable"] as! Bool == true {
if cellDescriptors[indexPath.section][indexOfTappedRow]["isExpanded"] as! Bool == false {
// INTERESTING BIT: Animates cell contents to Right
if currentCellDescriptor["cellIdentifier"] as! String == "CellHeader" {
UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 12, options: .CurveLinear, animations: {
cell.headerTitleLeftConstraint.priority = 999
cell.headerTitleRightConstraint.priority = 1
cell.layoutIfNeeded()
}, completion: nil)
}
} else if cellDescriptors[indexPath.section][indexOfTappedRow]["isExpanded"] as! Bool == true {
// MARK: Animates cell contents back to left
if currentCellDescriptor["cellIdentifier"] as! String == "CellHeader" {
UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 12, options: .CurveLinear, animations: {
cell.headerTitleLeftConstraint.priority = 1
cell.headerTitleRightConstraint.priority = 999
cell.layoutIfNeeded()
}, completion: nil)
}
}
First, don't use dequeueReusableCellWithIdentifier
here. It will use a cell not visible on screen and prepare to show it. What you want is cellForRowAtIndexPath
which returns a cell already on screen at the given indexPath
.
Then I understand you want to play with 2 constraint and animate the layout changes. In order to do so, the animation should only contain layoutIfNeeded
:
cell.headerTitleLeftConstraint.priority = 999
cell.headerTitleRightConstraint.priority = 1
UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 12, options: .CurveLinear, animations: {
cell.layoutIfNeeded()
}, completion: nil)
I'd also advice you to transfer this logic from the controller to your CustomCell
class. For example use the selected
attribute and the setSelected(animated: Bool)
to handle the state change visually.