4

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
    }

}
JoeVictor
  • 1,806
  • 1
  • 17
  • 38
  • How about you set the `UICollectionView's` property `isPagingEnabled` to `true` yet? – Zonily Jame Jul 12 '17 at 23:51
  • I did that for another project of mine. The problem with this is that paging snaps to increments of the screen width, cells are very tiny and snap vertically as well as horizontally – JoeVictor Jul 13 '17 at 02:54
  • If that is so, then this might help https://stackoverflow.com/questions/42486960/uicollectionview-horizontal-paging-with-space-between-pages – Zonily Jame Jul 13 '17 at 03:24
  • The problem with that is that is needs `UICollectionViewFlowLayout` which breaks the code from the tutorial for some reason... – JoeVictor Jul 13 '17 at 22:15
  • 1
    Can we please see your attempt at using the `...FlowLayout` please? Maybe your implementation is a little off? – Daniel Jul 14 '17 at 02:24

1 Answers1

2

I believe a solution to your problem would be to scroll the collection view to the indexPath of what award you want to be centered since a collection view is a subclass of a scroll view. You can scroll the collection view to the item via:

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

where indexPath is the indexPath that you would like to scroll to. This automatically animates your scroll, however if you'd like to customize you can call the UIView.animate function

Ali
  • 1,002
  • 1
  • 11
  • 21