UICollectionView 的单元格在滚动后并不总是刷新

Posted

技术标签:

【中文标题】UICollectionView 的单元格在滚动后并不总是刷新【英文标题】:Cell of UICollectionView not always refreshed after a scroll 【发布时间】:2012-11-19 20:32:37 【问题描述】:

我在我的 Storyboard (iPad) 中定义了一个包含 UICollectionView 的视图,在视图的底部还有一个 UIToolbar。 在UICollectionView 中,我添加了一个UICollectionViewCell(由iPadCellCollectionViewCell 类实现),其中包含另一个视图,即Core-Plot Graph(CPTGraphHostingView 类)。

我有一个名为 X 的类,它实现了 UICollectionViewDelegateUICollectionViewDataSource

在 X 类中,我为视图的每个单元格(在 ViewDidLoad 中)构建 Core-Plot 图表,并且我有以下代码将图表链接到 UICollectionViewCell 的单元格

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
static NSString* cellId = @"ChartCollectionId"; 

iPadCellCollectionViewCell* cell = [self.theCollectionView dequeueReusableCellWithReuseIdentifier:cellId forIndexPath:indexPath];

MyChart* chart = [_charts objectAtIndex:indexPath.row];

cell.hostingView.hostedGraph = chart.barChart;

return cell;

一切正常,我的所有图表都正确显示在屏幕上。当用户滚动视图时会出现此问题,然后一个或多个单元格变为“空白”。我真的不明白为什么。

我找到了一个变通方法,而不是在Interface Builder的UICollectionViewCell中添加CPTGraphHostingView,我自己构建了它,之前的代码变成了:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
static NSString* cellId = @"ChartCollectionId"; 

iPadCellCollectionViewCell* cell = [self.theCollectionView dequeueReusableCellWithReuseIdentifier:cellId forIndexPath:indexPath];


[cell.contentView addSubview:[_hostingViews objectAtIndex:indexPath.row]];

return cell;

使用此代码,一切正常。当我在 IB 中添加 CPTGraphHostingView 中的 UICollectionViewCell 时,是否有任何解释为什么它不起作用?

每次调用方法时调用“addSubview”是否有问题?没有内存泄漏?

【问题讨论】:

【参考方案1】:

我也遇到过类似的问题。我通过在我的自定义内容上调用 setFrame: 时强制重新绘制来修复它。在您的情况下,继承 CPTGraphHostingView 并覆盖此方法:

-(void)setFrame:(CGRect)frame 
    [super setFrame:frame];
    [self setNeedsDisplay]; // force drawRect:

编辑:重用单元格视图时刷新它们的更简单方法是在iPadCellCollectionViewCell 中覆盖applyLayoutAttributes:,如下所示:

-(void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes 
    // apply custom attributes...
    [self.hostingView setNeedsDisplay]; // force drawRect:

关于您的解决方法:内容视图中会有越来越多的子视图,这可能不是一件好事。但是,如果您在添加新子视图之前删除任何旧子视图,那也应该没问题。

【讨论】:

水平滚动时单元格呈现在错误位置时,我遇到了同样的问题,但不幸的是,这两个修复对我都不起作用。【参考方案2】:

这似乎是使用 sectionInsets 时 UICollectionView 中的一个错误。 单元格不会变得不可见,它们有时会在快速滚动时被放错位置。

因此,如果您通常每行有 3 个项目,那么您将在一行中获得第四个项目,但在下一行的第一个位置没有项目。

如果您将 UICollectionView 设置为不裁剪到边界,并将其移动到 UI 顶部, 您可能会看到这个未对齐的单元格。

到目前为止,我的解决方案是不使用 sectionInsets,而是使用 contentInset 和部分标题中的一些空白来包围它。

我还在 Twitter 上发现其他一些人也有同样的问题。 还有一个关于它的错误报告:12353513

【讨论】:

我在哪里查看该错误报告?

以上是关于UICollectionView 的单元格在滚动后并不总是刷新的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView 隐藏/防止单元格在 Sticky Header 后面滚动

UICollectionView 单元格在可见时不断重新加载

UICollectionView:ScrollToItem 到中心单元格在水平集合视图上不起作用

UICollectionView 单元格在几秒钟后消失或在点击屏幕时消失

集合视图,具有自定义布局,单元格在滚动时行为不端

UICollectionView 中重叠的单元格