UICollectionViewFlowLayout 子类:reloadData 后粘性单元格消失
Posted
技术标签:
【中文标题】UICollectionViewFlowLayout 子类:reloadData 后粘性单元格消失【英文标题】:UICollectionViewFlowLayout subclass: sticky cell disappearing after reloadData 【发布时间】:2015-05-07 01:41:17 【问题描述】:我有以下UICollectionViewFlowLayout
的子类:
@implementation MyFlowLayout
- (instancetype)init
self = [super init];
self.stickyIndexPaths = [NSMutableArray array];
return self;
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
return YES;
- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
CGRect collectionViewArea = CGRectMake(0.f, 0.f, self.collectionView.contentSize.width, self.collectionView.contentSize.height);
NSArray *attributes = [super layoutAttributesForElementsInRect:collectionViewArea].copy;
for (UICollectionViewLayoutAttributes *item in attributes)
[self makeStickyIfNeeded:item];
return attributes;
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
UICollectionViewLayoutAttributes *item = [super layoutAttributesForItemAtIndexPath:indexPath];
[self makeStickyIfNeeded:item];
return item;
- (void)makeStickyIfNeeded:(UICollectionViewLayoutAttributes*)item
BOOL indexPathIsSticky = [self.stickyIndexPaths indexOfObjectPassingTest:^BOOL(NSIndexPath *i, NSUInteger idx, BOOL *stop)
*stop = [i compare:item.indexPath] == NSOrderedSame;
return *stop;
] != NSNotFound;
if (indexPathIsSticky)
if (self.collectionView.contentOffset.y > item.frame.origin.y)
CGRect f = item.frame;
f.origin.y = self.collectionView.contentOffset.y;
item.frame = f;
item.zIndex = 1.f;
else
item.zIndex = 0.f;
从上面,我的想法是我可以添加单元格的 indexPaths 并使它们“粘”到顶部(假设是垂直流动),而粘滞单元格下方的任何其他单元格都在下面滚动。我正在使用单个粘性单元格测试此代码,在该单元格下方我有 30 个其他单元格(足以使内容偏移量大于粘性单元格的位置,这将导致它在其余单元格时粘住在它下面滚动)。到目前为止一切顺利。
但我注意到我的流程子类有 2 个副作用:
-
有时,当
UICollectionView
首次出现时,粘性单元格下方的单元格不会出现。如果我稍微滚动一下集合视图,它们就会出现。
如果我一直滚动到最后一个单元格(请记住,这意味着此时某些单元格已滚动到粘性单元格下方),然后从我的数据源中删除一个单元格并执行-reloadData
,而我得到正确的单元格数(比以前少一个),粘性标题不再可见。与第一种情况类似,如果我轻推集合视图,它会立即再次出现。
有什么想法吗?我认为这是新的 contentOffset 的问题,但事实并非如此。
【问题讨论】:
【参考方案1】:到目前为止,我发现的唯一解决方法是在我执行reloadData
之后,立即告诉集合视图重新加载我要粘贴的项目。也就是说,考虑到在我的示例代码中布局对象有一个 stickyIndexPaths 数组,我可以这样做:
[self.collectionView reloadData];
[self.collectionView reloadItemsAtIndexPaths:self.layout.stickyIndexPaths];
(请注意,我在视图控制器中保留了对集合视图布局的引用)。
这可以防止粘性细胞消失,但我仍然不知道它们为什么会消失。
【讨论】:
以上是关于UICollectionViewFlowLayout 子类:reloadData 后粘性单元格消失的主要内容,如果未能解决你的问题,请参考以下文章