I am stumbling into an issue with isHighlighted
state of an imageView inside a cell of a collection view: I cannot manage to animate the transition between 2 images the way I aim for.
Each custom cell of my collection view has 3 views:
When I touch the cell, both ImageViews instantly move to highlighted state but I would like them to transition to this state instead (a simple CrossDissolve transition)
I have tried 2 different approaches : overriding isSelected
method in the custom cell class and putting the animation in collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
Overriding isSelected property:
override var isSelected: Bool {
didSet {
UIView.transition(with: cellImageView, duration: 1, options: .transitionCrossDissolve, animations: {
self.cellImageView.setNeedsLayout()
self.cellImageView.layoutIfNeeded()
self.cellImageView.isHighlighted = self.isSelected
})
}
}
With this way, I get no animation when I click on the cell in the simulator, either when the cell is selected or when it loses it selected state, except when I click and hold a cell: then I get an animation of the previous cell losing its selected cell (in other words I have the transition of the previous selected imageView from isHighlighted(true)
to isHighlighted(false)
).
didSelectItemAt indexPath Method
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath) as! SubMenuCell
UIView.transition(with: cell, duration: 1.0, options: .transitionCrossDissolve, animations:
cell.setNeedsLayout()
cell.layoutIfNeeded()
cell.cellImageView.isHighlighted = cell.isSelected
})
}
This method does not trigger an animation when the cell is selected but does provide a transition animation when the cell moves from isSelected(true)
to isSelected(false)
: in other words, I see the previous selected cell fading out and I don't see the selected cell fading in.
I'd be grateful for any tips as to why it does not work and how it could be fixed!
Thank you all for the time you took to read and reply! Best,
Thanks to the guys to have taken the time to think about my question.
By investigating further, I decided to check how and when 3 events, namely cell.isHighlighted
, cell.isSelected
and collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
where triggered and I found some pretty interesting things actually. Let me sum it up:
When you touch a cell (cell1) in a collection view, it appears the following events occur:
cell1.isHightlighted
is set to true
cell1.isHightlighted
is set to false
cell1.isSelected
is set to true
, which calls back cell1.isHighlighted
propertycollectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
method is calledNow when you touch another cell (cell2) in the collection View, the following events occur:
cell2.isHighlighted
is set to true
cell1.isSelected
is set to false
, which calls back cell1.isHightlighted
propertycell2.isHighlighted
is set to false
cell1.isSelected
is set to false
again (!)cell2.isSelected
is set to true
, which calls back cell2.isHighlighted
propertycollectionView(_ collectionView:
UICollectionView, didSelectItemAt indexPath: IndexPath)
method is
calledWith that in mind, I came to the conclusion that to run a transition animation on isHighlighted
state in the collection view method will never work as intended since the property has already been set prior to reach the method.
One solution to obtain both animations (isHighlighted
true
and false
) that I have found is to act on the property observers of isHighlighted
and isSelected
of my custom collection view cell, as follow:
override var isHighlighted: Bool {
willSet {
if newValue == true {
UIView.transition(with: cellImageView, duration: 1.0, options: .transitionCrossDissolve, animations: {
self.cellImageView.isHighlighted = newValue
})
}
}
}
override var isSelected: Bool {
willSet {
if newValue == false {
UIView.transition(with: cellImageView, duration: 1.0, options: .transitionCrossDissolve, animations: {
self.cellImageView.isHighlighted = newValue
})
}
}
}
I hope it helps, and thanks again to all of you whom have spent some time trying to figuring it out! If anyone finds a more elegant solution, do not hesitate to post it!!! Best,