Reputation: 3052
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
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