UICollectionView 重新加载数据导致图形故障

Posted

技术标签:

【中文标题】UICollectionView 重新加载数据导致图形故障【英文标题】:UICollectionView reload data causing graphical glitching 【发布时间】:2019-04-06 17:53:51 【问题描述】:

我正在尝试制作自定义颜色选择器。左边的颜色是选择的颜色,其他颜色是其他选项。但是,当我 reloadData() 时,collectionView 边缘的一个单元格将在这个新单元格下方有一个先前的单元格。

我尝试制作自定义 collectionViewCell,然后将视图添加到默认 UICollectionViewCell。 我试图通过对视图应用阴影效果来诊断问题,这就是我知道单元格相互堆叠的方式。 以前我通过在情节提要中制作原型单元来对 collectionView 进行编码,但是对于我想要的功能,我无法做到这一点。

这是 cellForItemAtIndexPath 和重新加载集合视图时的代码。

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = self.dequeueReusableCell(withReuseIdentifier: "colorCell", for: indexPath)
        var color = UIColor.white
        if colors.count == 0
            color = UIColor(red: CGFloat(mainManager.colors[indexPath.row][0] ), green: CGFloat(mainManager.colors[indexPath.row][1] ), blue: CGFloat(mainManager.colors[indexPath.row][2] ), alpha: 1.0)
        
        else
            color = UIColor(red: CGFloat((colors[indexPath.row][0] ) ), green: CGFloat((colors[indexPath.row][1] ) ), blue: CGFloat((colors[indexPath.row][2] ) ), alpha: 1.0)
        
        if indexPath.row == 0
            let cellView = UIView()
            cell.addSubview(cellView)
            cellView.translatesAutoresizingMaskIntoConstraints = false
            cellView.centerYAnchor.constraint(equalTo: cell.centerYAnchor).isActive = true
            cellView.centerXAnchor.constraint(equalTo: cell.centerXAnchor).isActive = true
            cellView.widthAnchor.constraint(equalTo: cell.widthAnchor, multiplier: 0.8).isActive = true
            cellView.heightAnchor.constraint(equalTo: cell.heightAnchor, multiplier: 0.8).isActive = true
            cellView.roundEdgesAndShadow()
            cellView.backgroundColor = color
        
        else
            let centerView = UIView()
            cell.addSubview(centerView)
            centerView.translatesAutoresizingMaskIntoConstraints = false
            centerView.centerXAnchor.constraint(equalTo: cell.centerXAnchor).isActive = true
            centerView.centerYAnchor.constraint(equalTo: cell.centerYAnchor).isActive = true
            centerView.widthAnchor.constraint(equalTo: cell.widthAnchor, multiplier: 0.4).isActive = true
            centerView.heightAnchor.constraint(equalTo: cell.heightAnchor, multiplier: 0.4).isActive = true
            centerView.roundEdgesAndShadow()
            centerView.backgroundColor = color
        
        return cell
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
        if colors.count == 0
            colors = mainManager.colors.sorted(by:  (a, b) -> Bool in
                if a == mainManager.colors[indexPath.row]
                    return true
                
                else
                    return false
                
            )
        
        else
            colors = mainManager.colors.sorted(by:  (a, b) -> Bool in
                if a == self.colors[indexPath.row] 
                    return true
                
                else
                    return false
                
            )
        
        self.reloadData()
    

【问题讨论】:

永远不要在cellForItem 中添加视图,这实际上是使用collectionView 时最糟糕的做法之一。改为子类UICollectionViewCell 并在那里添加您需要的所有子视图。然后只 dequeuecellForItem 中的单元格并传递单元格可能需要的数据或模型。 【参考方案1】:

由于您正在动态地将视图添加到单元格中,因此在重用的情况下它们会多次添加到同一个单元格中。在集合视图单元格的 prepareForReuse 中删除其所有子视图。

【讨论】:

以上是关于UICollectionView 重新加载数据导致图形故障的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView:重新加载数据,不删除单元内动画

UICollectionView如何从委托中重新加载数据

UICollectionView 重新加载数据不会更新单元格

在 UICollectionView 中重新加载数据的正确方法是啥?

UICollectionView 不重新加载数据

UICollectionView 上的自定义动画重新加载数据