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

Setup:

I currently have one UICollectionView, which is a set of circles for cells that mimic the interface of the Apple Watch home screen. I did this by following this guide . In case you haven’t read the article or for some reason it doesn’t work, it’s basically a UICollectionView of circles with external ones that decrease when you scroll them from the center.

Problem:

I want the bubbles to be displayed dynamically so that whenever a user receives a reward, the reward “appears”, that is, is animated, scales from 0 to 1. However, I would like all the cells to always be centered. Therefore, when, for example, the user jumps from 1 award to two, I want the first of them to move to the left, and the new one to enter.

What I tried:

I tried to implement a method UICollectionView insetForSectionAt, but it does not work. I suspect because CollectionView is not one of FlowLayout. I tried to turn it into one, but in the end I broke everything ...

The code:

Here's what I implemented, just in case the article is omitted. (condensed for readability):

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 scale**

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

        //Set the cell 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
    }

}
+4
1

, , indexPath , , . :

collectionView?.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)

indexPath - , . , , , UIView.animate

+2

Source: https://habr.com/ru/post/1680995/


All Articles