UICollectionView targetContentOffsetForProposedContentOffset:由UIScrollView重写

时间:2017-12-28 14:18:38

标签: objective-c uiscrollview uicollectionview uicollectionviewlayout uicollectionviewflowlayout

当我在顶部插入一些项目时,我有一个自定义的UICollectionViewFlowLayout我会计算出合适的并从targetContentOffsetForProposedContentOffset:返回。

问题在于,在名为UIScrollView的方法中,_smoothScrollDisplayLink:顶部的第一次插入批量更新会覆盖从targetContentOffsetForProposedContentOffset:返回的值的contentOffset一个值完全关闭(我返回例​​如900s它将它覆盖到500s)

BUT

在以下插入批量更新中,UISCrollView方法设置的值非常合理。

更多信息#1:

我尝试在顶部插入项目,但保持滚动位置不变,所以基本上我将内容偏移设置为当前contentOffset +插入更新之前和之后的高度增量

更多信息#2: 这是我记录的一些真实值:

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:)

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。试试这个黑客:

  1. flowLayout保存上一个目标contentOffset

    - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset
    {
        CGPoint contentOffset = [super targetContentOffsetForProposedContentOffset:proposedContentOffset];
    
        _lastTargetContentOffset = contentOffset;
    
        return contentOffset;
    }
    
  2. collectionView覆盖方法setContentOffset中,如下所示:

    - (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];
        }
    }