Henny Lee
Henny Lee

Reputation: 3052

how to animate text label color changes during UITableViewCell selection?

I'm trying to create a custom selection style for my table view cells by creating a subclass of UITableViewCell. When I click a cell, I want it to change color and fade back to the original color. I've read other posts on SO like this one, but it doesn't seem to work.

Edit: selectionStyle is set to .None.

When I use setHighlighted(_:), the color doesn't change immediately and only happens when the tap lasts for like 0.5 sec.

I've also used setSelected(_:). The color changes right away but won't change back. So I added deselectRowAtIndexPath(_:) in tableView(didSelectRowAtIndexPath:) but this causes no changes at all. Then I tried using tableView.reloadRowsAtIndexPaths(_:) and finally the color changes and goes back to the original color. But unfortunately it doesn't animate the last part, fading back to the original color. Also I noticed that after the color changed, it also dimms the original color (caused by tableView.reloadRowsAtIndexPaths(_:)).

I gave up on using setSelected(_:) and setHighlighted(_:) and tried using touchesBegan(_:) and touchesEnded(_:). To keep it short, same as above...

These are the codes I've tried using (not all together).

In the subclass of UITableViewCell:

override func setSelected(selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    label.textColor = selected ? UIColor.redColor() : UIColor.blackColor()
}

override func setHighlighted(highlighted: Bool, animated: Bool) {
    label.textColor = highlighted ? UIColor.redColor() : UIColor.blackColor()
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    super.touchesBegan(touches, withEvent: event)

    label.textColor = UIColor.redColor()
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    super.touchesEnded(touches, withEvent: event)

    let changeEnded = CATransition()
    changeEnded.duration = 0.5

    nameLabel.layer.addAnimation(changeEnded, forKey: nil)
    nameLabel.textColor = .blackColor()
}

In the table view controller (not together either):

tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)

tableView.deselectRowAtIndexPath(indexPath, animated: true)

Upvotes: 2

Views: 989

Answers (1)

Henny Lee
Henny Lee

Reputation: 3052

I somehow managed to solve it, but it just doesn't feel like this is how it should be done. Shouldn't it be much simpler to animate such a simple animation for an UILabel?

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let selected = tableView.cellForRowAtIndexPath(indexPath) as! CustomViewCell

    let changeColor = CATransition(); changeColor.duration = 1

    CATransaction.begin()

    CATransaction.setCompletionBlock {
        selected.label.layer.addAnimation(changeColor, forKey: nil)
        selected.label.textColor = .blackColor()
    }

    selected.nameLabel.textColor = .redColor()

    CATransaction.commit()
}

Upvotes: 4

Related Questions