I have implemented expand/ collapse animation, for a UICollectionView
with dynamic cell height (Because different cell has different content).
This is the summary of my implementation
- I am using
UICollectionViewCompositionalLayout
, because I want the cell able to adjust its own height to accommodate its content. (https://stackoverflow.com/a/51231881/72437) - I am using
UIStackView
in the cell. Reason is that, once I hide one of theUITextView
s in the cell, I do not want the hiddenUITextView
to still occupy the space. UsingUIStackView
can avoid me from dealing with zero height constraint. - I am using
performBatchUpdates
andlayoutIfNeeded
to achieve the animation, based on https://stackoverflow.com/a/69043389/72437
Here's the final outcome - https://www.youtube.com/watch?v=2uggmpk0tJc
As you can see, the overall effect isn't really smooth, espcially when I toggle in between "Color" and "Print PDF", which are having larger content height.
This is what happen when I tap on the cell
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
var indexPaths = [IndexPath]()
for i in (0..<isExpanded.count) {
if isExpanded[i] != false {
isExpanded[i] = false
indexPaths.append(IndexPath(item: i, section: 0))
}
}
if isExpanded[indexPath.item] != true {
isExpanded[indexPath.item] = true
indexPaths.append(IndexPath(item: indexPath.item, section: 0))
}
collectionView.performBatchUpdates({}) { _ in
collectionView.reloadItems(at: indexPaths)
collectionView.layoutIfNeeded()
}
}
Do you have any idea, what else thing I can try out, so that the animation will look smoother? This is the complete code example for demonstration
https://github.com/yccheok/shop-dialog
Thank you!
CodePudding user response:
You can get close to your goal by changing didSelectItemAt
to this:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
for i in (0..<isExpanded.count) {
if i == indexPath.item {
// toggle selected row
isExpanded[i].toggle()
} else {
// set all other rows to false
isExpanded[i] = false
}
if let c = collectionView.cellForItem(at: IndexPath(item: i, section: 0)) as? CollectionViewCell {
c._description.isHidden = !isExpanded[i]
}
}
collectionView.performBatchUpdates(nil, completion: nil)
}
The default animation / compression of elements when showing and hiding elements in stack views is not always acceptable though. If you want to try to refine it, take a look at this discussion: