Skip to content

Instantly share code, notes, and snippets.

@KelvinJin
Last active July 14, 2021 04:31
Show Gist options
  • Save KelvinJin/18a83c02e94031bacd1d352adecfc060 to your computer and use it in GitHub Desktop.
Save KelvinJin/18a83c02e94031bacd1d352adecfc060 to your computer and use it in GitHub Desktop.
import UIKit
class ParallaxCollectionViewLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
return super.layoutAttributesForElements(in: rect)?.flatMap { $0.copy() as? UICollectionViewLayoutAttributes }.flatMap(addParallaxToAttributes)
}
// We need to return true here so that everytime we scroll the collection view, the attributes are updated.
override public func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}
private func addParallaxToAttributes(_ attributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
guard let collectionView = self.collectionView else { return attributes }
let width = collectionView.frame.width
let centerX = width / 2
let offset = collectionView.contentOffset.x
let itemX = attributes.center.x - offset
let position = (itemX - centerX) / width
let contentView = collectionView.cellForItem(at: attributes.indexPath)?.contentView
if abs(position) >= 1 {
contentView?.transform = .identity
} else {
let transitionX = -(width * 0.5 * position)
contentView?.transform = CGAffineTransform(translationX: transitionX, y: 0)
}
return attributes
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment