UICollectionView and UICollectionViewCell animate frame

I have a requirement to animate UICollectionView and UICollectionViewCell frame. The end results is what I but in between there appear to be some phantom cells being mixed in with actual cells being animated. The CV animates to a different size and the CV cells are to match the new size based on settings given to CV's collectionViewLayout.

Here's the starting point:

Here's how the animation starts to look:

The end result is as expected:


My final intent is to do this with a UIViewPropertyAnimator() but you see the same problem even if the animation is triggered with a standard UIView animation.


The main method called is prepareLayout().


internalfunc prepareLayout() {
    let spacing = buttonTheme.spacing * 2.0
   
//    let theLayout = UICollectionViewFlowLayout()

    theLayout.invalidateLayout()

    buttonsView.frame = viewModel.frame
    theLayout.itemSize = itemSize
    theLayout.minimumInteritemSpacing = spacing
    theLayout.minimumLineSpacing = spacing
   
    // Needed to correct problem where sometimes only one row (instead of two) shows in iOS 10.x
    buttonsView.contentInset = UIEdgeInsets(top: spacing, left: spacing, bottom: spacing, right: spacing)

//    buttonsView.performBatchUpdates({
      buttonsView.setCollectionViewLayout(theLayout, animated: true)
      self.buttonsView.reloadData()
//    }, completion: nil)

    buttonsView.setCollectionViewLayout(theLayout, animated: true)
  }

As can seen, I've been playing around with CV's performBatchUpdates() and setCollectionViewLayout() but to no avail. I need to reloadData() because things like the fontSize change during the animation which will be more important when using UIViewPropertyAnimator().

My cell is a subclass of UICollectionViewCell that has a UIButton in it. The interaction of the button is disabled so I can handle everything in the CV.


Any idea on how to correct this problem is appreciated.

Replies

I would not reloadData during animation (I would suspect this being the cause of phantom cells).


Have you defined a custom UICollectionViewCell ? And set the font in the draw func.

Not calling reloadData() didn't help. And, yes, as stated in my original email I have a custom CV cell with only a button in it.

I've created a public repo that's essentially a stripped down version of the app that shows the issue; see

https://github.com/Phantom-59/CVAnimatorTest


Would appreacite any ideas on correting the problem.

Where do you change font size (of whcih object ? The button ?), as I understand it is an important aspect of the animation ?


Anyway, I wouyld not reloadData in the midst of animation.

Presently I change the font in a method that populates the button in the CV cell. But I've commented this out completely such that the font is not changed at all during the animation and I still get these "ghost" cells.


Check out my this repo which is a stripped down version of the that shows the issue. You can comment out the setting of the font in line #4 and still see the problem.


public func populate(for tag: Int, using pointSize:CGFloat) {
    self.tag = tag
  
    titleLabel?.font = UIFont.systemFont(ofSize: pointSize )
    titleLabel?.adjustsFontSizeToFitWidth = true
        
    let title = "\(tag)"
    setTitle(title, for: .normal)
    setTitleColor(UIColor.white, for: .normal)
    backgroundColor = UIColor.blue
    
    setNeedsDisplay()
  }

Still looking for an answer. Have submitted bug report 48004062.