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

Posted

技术标签:

【中文标题】UICollectionView 单元格在可见时不断重新加载【英文标题】:UICollectionView cells keeps reloading when they become visible 【发布时间】:2014-03-05 00:40:48 【问题描述】:

我有一个包含自定义单元格的集合视图,只要单元格在屏幕上可见,它们就会不断重新加载,例如集合视图已向下滚动,然后又向上滚动,以便单元格再次可见。我想关闭它,并希望单元格只加载一次,而不是每次可见时都刷新。这是我初始化单元格的代码。

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:  (NSIndexPath *)indexPath

  NSLog(@"cell row %d is being refreshed", indexPath.row);
  static NSString *CellIdentifier = @"Cell";

  LevelCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
  Level *levelTemp =[levels objectAtIndex:indexPath.item];

  [[cell levelNumber]setText:[NSString stringWithFormat:@"Level %@",levelTemp.level]];

  DataClass *obj=[DataClass getInstance];
  obj.totalC=obj.totalC+([levelTemp.comp_questions intValue]);
  obj.totalQ=obj.totalQ+([levelTemp.max_questions intValue]);
  int unlockA = [levelTemp.unlockAmount intValue];

  return cell;

【问题讨论】:

没有。不,你没有。这正是表视图和集合视图的设计方式。您只需要在内存中保留与屏幕上一样多的单元格...如果您尝试将所有这些单元格保留在内存中,则会大大降低性能... njgrif 是正确的,但是如果您不关心性能损失,请给每个单元格一个唯一的单元格标识符,它将每个单元格生成一次,而不是重复使用它们。 这不是真的,@box86rowh 这实际上是两全其美。它会将单元格保存在内存中......但它仍然会在它们被放到屏幕上之前重新加载它们。 归根结底,collection view cell 是一个 UI 元素,仅当它要出现在屏幕上时才需要在内存中。这是一个 XY 问题...还有其他一些原因,您认为需要将其保存在内存中...如果您能解释原因是什么,我们可以帮助您完成实际需要做的事情。跨度> 啊,谢谢你的信息 【参考方案1】:

这是个坏主意。处理这个问题的正确方法是让levels 存储所有需要的数据,从集合视图中获取下一个单元格并用来自levels 的数据填充它。它既节省内存又节省时间。


有一个NSMutableArray 来保存LevelCells。由于不知道请求单元格的顺序,因此您需要预先初始化数组。它需要与levels 大小相同,值需要为[NSNull null]

self.cells = [NSMutableArray arrayWithCapacity:[levels count]];
for (NSUInteger i = 0; i < [levels count]; ++i) 
    self.cells[i] = (id)[NSNull null];

这可以在您的-viewDidLoad 中,也可以作为延迟加载的属性。

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

    // Look to see if there is a cell at this index
    LevelCell *cell = self.cells[indexPath.item];

    if (cell == (id)[NSNull null]) 
        NSLog(@"cell row %d is being refreshed", indexPath.item);
        static NSString *CellIdentifier = @"Cell";

        cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
        Level *levelTemp =[levels objectAtIndex:indexPath.item];

        [[cell levelNumber]setText:[NSString stringWithFormat:@"Level %@",levelTemp.level]];

        DataClass *obj=[DataClass getInstance];
        obj.totalC=obj.totalC+([levelTemp.comp_questions intValue]);
        obj.totalQ=obj.totalQ+([levelTemp.max_questions intValue]);
        int unlockA = [levelTemp.unlockAmount intValue];

        // save the new cell in the array.
        self.cells[indexPath.item] = cell;
    

    return cell;

最后说明:self.cells 在数据更新时不会更新。您将需要手动执行此操作。更改、插入和删除都需要在 levelsself.cells 之间进行镜像。

同样,这是一个坏主意。真的,不要这样做。

【讨论】:

以上是关于UICollectionView 单元格在可见时不断重新加载的主要内容,如果未能解决你的问题,请参考以下文章

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

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

UICollectionView 中的大单元格在仍显示的情况下被删除

为啥我的 UICollectionView 单元格在我的 swift ios 应用程序中不可点击?

UICollectionView 单元格在swift中使用约束固定宽度和动态高度

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