如何在回滚以查看 swift 时停止收集触发代码

问题描述

我是新手,如果我的标题没有正确表达,我深表歉意。我一直在破解,一直无法找到这个问题的答案。

我有一个水平滚动的集合。我试图根据 Firestore 数组中保存的投票数据,以编程方式将 CGRect 添加到集合中的相关项目,以直观地显示投票结果。

这是有效的,但问题是当您滚动离开(因此集合中的项目不在屏幕上)然后返回时,再次触发绘制 CGRects 的代码并且更多图形被添加到视图中。有没有办法在用户将项目集合滚动到屏幕外时删除这些 CGRects,以便当用户将项目滚动回视图时,再次触发代码不会创建重复项?

以下是显示第一次和第二次加载的几个屏幕截图

First load

Second load

这是我的代码(单元格 b 是 CGrect 被触发的地方)

//COLLECTION VIEW CODE    
func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if collectionView == self.sentCollectionView {
            let cellA = collectionView.dequeueReusableCell(withReuseIdentifier: "sCell",for: indexPath) as! SentCollectionViewCell
            
            cellA.sentQuestionLabel.text = sentMessages[indexPath.row].shoutText
            // Set up cell
            return cellA
        }
        else {
            let cellB = receivedCollectionView.dequeueReusableCell(withReuseIdentifier: "pCell",for: indexPath) as! ReceivedCollectionViewCell
            
            receivedMessages[indexPath.row].pollTotal = receivedMessages[indexPath.row].pollResults.reduce(0,+)
            print("Sum of Array is : ",receivedMessages[indexPath.row].pollTotal!)
            cellB.receivedShoutLabel.text = receivedMessages[indexPath.row].shoutText
            
            print(receivedMessages[indexPath.row].pollResults.count)
            
            if receivedMessages[indexPath.row].pollResults != [] {
                for i in 0...receivedMessages[indexPath.row].pollResults.count - 1 {
                    cellB.resultsView.addSubview(sq(pollSum: receivedMessages[indexPath.row].pollTotal!,pollResult: receivedMessages[indexPath.row].pollResults[i]))
                }
            }

            return cellB
        }
    }

//THIS DRAWS THE CGRECT
    func sq(pollSum: Int,pollResult: Int) -> UIView {
        // divide the width by total responses
        let screenDivisions = Int(view.frame.size.width) / pollSum

        // the rectangle top left point x axis position.
        let xPos = 0
        
        // the rectangle width.
        let rectWidth = pollResult * screenDivisions
        
        // the rectangle height.
        let rectHeight = 10
        
        // Create a CGRect object which is used to render a rectangle.
        let rectFrame: CGRect = CGRect(x:CGFloat(xPos),y:CGFloat(yPos),width:CGFloat(rectWidth),height:CGFloat(rectHeight))
        
        // Create a UIView object which use above CGRect object.
        let greenView = UIView(frame: rectFrame)
        
        // Set UIView background color.
        greenView.backgroundColor = UIColor.green
        
        //increment y position
        yPos = yPos + 25
        
        return greenView
        
    }

解决方法

集合的单元格出列 dequeueReusableCell ,您需要覆盖 prepareForReuse

或者设置一个标签

greenView.tag = 333

然后在 cellForItemAt 里面这样做

cellB.resultsView.subviews.forEach {  
   if $0.tag == 333 {
      $0.removeFromSuperview()
    }
}
if receivedMessages[indexPath.row].pollResults != [] {
    for i in 0...receivedMessages[indexPath.row].pollResults.count - 1 {
        cellB.resultsView.addSubview(sq(pollSum: receivedMessages[indexPath.row].pollTotal!,pollResult: receivedMessages[indexPath.row].pollResults[i]))
    }
}