Home > Enterprise >  How to achieve smooth expand/ collapse animation in UICollectionView with dynamic cell height?
How to achieve smooth expand/ collapse animation in UICollectionView with dynamic cell height?

Time:04-17

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

  1. 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)
  2. I am using UIStackView in the cell. Reason is that, once I hide one of the UITextViews in the cell, I do not want the hidden UITextView to still occupy the space. Using UIStackView can avoid me from dealing with zero height constraint.
  3. I am using performBatchUpdates and layoutIfNeeded 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:

Change default StackView animation

  • Related