0

I am trying to apply a kind of reverse-parallax effect on the first cell in my collectionview by overriding the layoutAttributesForElements(in rect:) method on UICollectionViewCompositionalLayout, calling the super implementation to obtain the default values then manipulating the frame of only the item at indexPath (0,0).

class ScrollingCardCollectionViewLayout: UICollectionViewCompositionalLayout {
    override func shouldInvalidateLayout(forBoundsChange _: CGRect) -> Bool {
        return true
    }

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let attrs = super.layoutAttributesForElements(in: rect)
        guard let attrs = attrs, let collectionView = collectionView else { return attrs }
        if let attr = attrs.first(where: { $0.representedElementCategory == .cell && $0.indexPath.section == 0 && $0.indexPath.item == 0 }) {
            let offset = collectionView.contentOffset
            let inset = collectionView.contentInset
            let adjustedOffset = offset.y + inset.top

            attr.frame.origin.y = adjustedOffset / 3 * 2
        }
    }
}

This works perfectly when scrolling slowly, however if you scroll quickly it the scrollview seems to lose track of its contentOffset and jerks back 3-5 times. This occurs both when both panning to scroll or 'flicking' to allow it to animate / decelerate. It also starts working perfectly once you have scrolled to the bottom of the content at least once (i.e. once the layout has established the heights of all the index paths).

Example scrolling

I am using a vertical UICollectionViewCompositionalLayout with fixed full-screen width and dynamically sized (height) cells.

Full sample project available here

I've also tried setting an affine transform translation on the layout attributes which yielded the same results. Is this an iOS bug or am I doing something I shouldn't be?

JoGoFo
  • 1,928
  • 14
  • 31
  • try play around and adjust the contentOffset using [this method](https://developer.apple.com/documentation/uikit/uicollectionviewlayout/1617724-targetcontentoffset). Maybe it'll help you avoid it. – Maksym Musiienko Sep 26 '22 at 11:13
  • I actually had this implemented already with some custom logic but removed it in case it was interfering. This doesn't get called while you are panning though, only when you let go to complete the deceleration animation. My issue occurs while panning. – JoGoFo Sep 26 '22 at 23:51

0 Answers0