0

I have a custom UICollectionViewFlowLayout when I insert some items at the top I calculate the appropriate and return it from targetContentOffsetForProposedContentOffset:.

The problem is on the first insertion batch updates at the top the UIScrollView in method called _smoothScrollDisplayLink:override the contentOffset from the value returned from targetContentOffsetForProposedContentOffset: by a value that's completely off (I return for example 900s it overrides it to 500s)

BUT

On the following insertion batch updates the values set by the UISCrollView method is very reasonable.

More info #1:

I try to insert items at the top but keep the scrolling position constant so basically I set the content offset to the current contentOffset + delta in height between before and after the insertion updates

More info #2: Here's some real values I logged:

current offset=95.500000, newHeight=1835.007812, oldHeight=936.003906
new offset = 994.503906
set content offset: 550.000000 before: 994.503906  (by _smoothScrollDisplayLink:)

current offset=95.500000, newHeight=2771.011719, oldHeight=1835.007812
new offset = 1031.503906
set content offset: 1026.500000 before: 1031.503906 (by _smoothScrollDisplayLink:)
Yousef Hamza
  • 347
  • 1
  • 3
  • 13

1 Answers1

1

I've got a same problem. Try this hack:

  1. In your flowLayout save last target contentOffset:

    - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset
    {
        CGPoint contentOffset = [super targetContentOffsetForProposedContentOffset:proposedContentOffset];
    
        _lastTargetContentOffset = contentOffset;
    
        return contentOffset;
    }
    
  2. In your collectionView override method setContentOffset like this:

    - (void)setContentOffset:(CGPoint)contentOffset
    {
        if (self.contentSize.height != self.collectionViewLayout.collectionViewContentSize.height)
        {
            MyCollectionViewFlowLayout * myCollectionLayout =  (MyCollectionViewFlowLayout *)self.collectionViewLayout;
            NSParameterAssert([myCollectionLayout isKindOfClass:MyCollectionViewFlowLayout.class]);
            [super setContentOffset:myCollectionLayout.lastTargetContentOffset];
        }
        else
        {
            [super setContentOffset:contentOffset];
        }
    }
    
Vladislav
  • 11
  • 2