【问题标题】:UICollectionView showing wrong cells after scrolling - dequeue issue?UICollectionView 在滚动后显示错误的单元格 - 出队问题?
【发布时间】:2012-10-31 17:47:50
【问题描述】:

我在 UIViewController 中有一个 UICollectionView。在 collectionView cellForItemAtIndexPath: 方法中,它根据数据源创建一系列自定义单元格。自定义单元格依次包含 UIView,子类化以绘制单个 PDF 页面。

它的设置方式是将 PDF 文件拆分为单个页面,因此单元格 1 包含 PDF 页面 1,单元格 2 包含 PDF 页面 2,依此类推。到目前为止一切顺利,这是我的问题:

当我向下滚动时,UICollectionView 开始显示错误的单元格。例如,在一个 34 页的文档中,它以正确的顺序显示单元格/第 1-16 页,但随后开始显示 似乎 已进一步向上出列的页面,例如单元格 1、单元格 2、单元格 4。我从来没有靠近单元格/第 34 页。

我过去曾在 UITableView 中看到过类似的行为,并且认为这与单元格的出列或委托方法有关。不太确定 - 任何帮助表示赞赏。

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

//create custom cell
CustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellID" forIndexPath:indexPath];

//set file name (always the same; one PDF file)
cell.fileName = fileName;
cell.backgroundColor = [UIColor clearColor];

//set the title to the page number
cell.title = [NSString stringWithFormat:@"page %@", [countArray objectAtIndex:indexPath.row]];

//set the current page (which indicates which page to display) according to the pageCount
cell.currentPage = [[countArray objectAtIndex:indexPath.row] intValue];

return cell; }

【问题讨论】:

  • 也许我也有同样的问题。你找到解决办法了吗?

标签: pdf uicollectionview uicollectionviewcell


【解决方案1】:

我遇到过类似的问题。这很可能是因为重用的单元格不会自己重绘。在您的自定义单元格的 content 类(您的 PDF 视图)中,如果框架更新,则触发重绘:

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

这对我有用。此外,如果您的单元格大小可能会发生变化,请设置自动调整大小掩码,使其填充空间

self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

在初始化期间。

【讨论】:

  • 这对我有用 - 谢谢你的帮助。从 UICollectionView 的 cellForItemAtIndexPath 内部调用上面的 setFrame 方法,强制 PDF 重绘。非常感谢。
  • 太棒了!可能没有必要自己调用setFrame:,因为无论如何集合视图都会这样做。
  • 设置调整大小掩码有帮助,
  • 我听从了 Chris 的建议,但实际上我需要在设置单元格之后和返回之前在单元格上调用 setNeedsDisplay
【解决方案2】:

使用 prepareForReuse 方法修复了类似问题

只需将此方法添加到您的自定义单元实现中

- (void)prepareForReuse {

     self.fileName = nil;
     self.title = nil;

     // add remaining properties 

}

【讨论】:

  • @PuneethKamath 你不需要调用这个方法,只需在你的 UICollectionViewCell 子类中添加这个
【解决方案3】:

我根据 Asatur Galstyan 的回答迅速修复了一个类似的问题。

将自定义类关联到情节提要中的单元格后,可以重写 prepareForReuse() 函数:

import UIKit

class SomeCollectionViewCell: UICollectionViewCell {

    @IBOutlet weak var exampleView: UIView!
    @IBOutlet weak var exampleLabel: UILabel!

    override func prepareForReuse(){
        super.prepareForReuse()
        exampleLabel.textColor = nil
        exampleView.backgroundColor = nil
        exampleView.layer.cornerRadius = 0
    }
}

prepareForReuse() 的默认实现除了Apple recommends calling the the super.prepareForReuse() when overriding anyway 之外什么都不做(至少在 iOS 10 中)。

【讨论】:

  • 根据您的示例,我发现prepareForReuse() 中的exampleView.setNeedsDisplay() 解决了这个问题。
猜你喜欢
  • 2017-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多