Swift UICollectionView 单元格神秘地重复

Swift UICollectionView Cells Mysteriously Repeat

我们正在尝试创建一个集合视图。在每个单元格中,用户可以选择一个图像并在文本字段中输入文本。我们注意到,在添加四个单元格后,当我们添加一个新单元格时,文本字段已经填充了之前单元格的信息。在我们的代码中,我们从不以编程方式填充文本字段(一开始是空的),我们允许用户这样做。有什么建议吗?

  func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Image", forIndexPath: indexPath) as! CollectionViewCell
    cell.deleteButton?.addTarget(self, action: #selector(AddNewItem.xButtonPressed(_:)), forControlEvents: UIControlEvents.TouchUpInside)
    cell.deleteButton?.layer.setValue(indexPath.row, forKey: "index")
    let item = items[indexPath.item]
    let path = getDocumentsDirectory().stringByAppendingPathComponent(item.image)
    cell.imageView.image = UIImage(contentsOfFile: path)
    cell.imageView.layer.borderColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.3).CGColor
    cell.imageView.layer.borderWidth = 2
    cell.layer.cornerRadius = 7

    return cell
}

问题是您正在使用 dequeReusableCellWithIdentifier,其中 returns 已经创建了单元格(您之前使用过)。这就是为什么它已经充满了以前的数据。您需要在显示此单元格之前清除此数据,或从某些存储中填充它(例如代表您的集合视图单元格的数组(数组中的每个对象以某种方式与单元格相关,在您的情况下是单元格中写的文本))

下面是我最终解决它的方法。

我创建了一个 Item class,其中包含集合视图单元格中显示的所有字段,并创建了一个项目数组。

这是我的 CollectionViewCell class 的简化版本,这里只有一个文本字段:

class CollectionViewCell: UICollectionViewCell {

    @IBOutlet weak var itemName: UITextField!

    var item: Item?

    func initializeListeners(){
        itemName.addTarget(self, action: #selector(itemNameChanged(_:)), forControlEvents: UIControlEvents.EditingChanged)
    }


    //When the item name is changed, make sure the item's info is updated
    func itemNameChanged(textField: UITextField) {
        item?.itemName = textField.text!
    }
}

这是我的视图控制器中 cellForItemAtIndexPath 函数的简化版本 class:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CollectionViewCell
    cell.initializeListeners()
    let item = items[indexPath.item]
    cell.item = item
    cell.itemName.text = item.itemName
    return cell
}

您可以在 UICollectionViewCell 自定义中使用它 class

override func prepareForReuse() {
    self.profileImg.image = #imageLiteral(resourceName: "Profile Icon Empty")

    super.prepareForReuse()
}

原因是collectionViewLayout.collectionViewContentSize.height

高于实物尺寸!建议让 UICollectionView 自动计算高度(不使用 UIScrollView,让 UICollectionView 保持滚动),因为手动更改会导致很多奇怪的行为。