Continuously center UICollectionView cells both vertically and horizontally whenever new ones appear

Viewed 493

The Setup:

I currently have a UICollectionView that is a bunch of circles for cells to mimic the UI of the Apple Watch home screen. I made it by following this guide. In case you didn't read the article or it goes down for some reason, it's basically a UICollectionView of circles with the outer ones being scaled down as you scroll them away from the center.

The Problem:

I want bubbles to pop up dynamically such that whenever a user earns an award, the award "pops" i.e. animates in, scaling from 0 to 1. However, I would like whatever cells there may be to be always centered. So when for example, the user jumps from 1 award to two, I want the first one to move to the left while the new one pops in.

What I've Tried:

I have tried implementing the UICollectionView's insetForSectionAt method, but it doesn't seem to work. I suspect it's because the CollectionView is not one with FlowLayout. I tried turning it into one but I ended up crashing everything...

The Code:

Here is what I have implemented, just in case the article goes down. (condensed for ease of reading):

class CollectionViewLayout: UICollectionViewLayout {
     //Invalidate the layout every time the bounds change so we can do the cool changes
    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        return true
    }

    override var collectionViewContentSize: CGSize {
        return CGSize(width:  self.itemSize * CGFloat(COLS),
                  height: self.itemSize * CGFloat(ROWS))
    }

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        var attributes: [UICollectionViewLayoutAttributes] = []
        for i in 0..<cellCount {
            let indexPath = IndexPath(item: i, section: 0)
            attributes.append(self.layoutAttributesForItem(at: indexPath)!)
        }

        return attributes
    }

    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        var attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)

        // **Code where I create "z" variable by using equation in article, where "z" is just a value [0,1] that determines cell's scale**

        // **More code where I Calculate "x" and "y" based on indexPath like in article**    

        //Set the cell's attributes:
        attributes.transform = CGAffineTransform(scaleX: z, y: z)
        attributes.size = CGSize(width: self.itemSize, height: self.itemSize)
        attributes.center    = CGPoint(x: x, y: y)

        return attributes
    }

}
1 Answers
Related