【问题标题】:new view created with every collectionView cell tap instead of updating the existing one每次点击 collectionView 单元格时都会创建新视图,而不是更新现有视图
【发布时间】:2021-03-09 16:36:04
【问题描述】:

我想在collectionView Cells 中有this ring progress view (cocoa pod)。当您点击一个单元格时,进度应该增加 0.1(0.0 = 0% 进度,1.0 = 100% 进度)。

不幸的是,它似乎总是在旧的进度视图之上创建一个新的进度视图,因为红色的阴影越来越深,您可以看到第二个/第三个/.. 环。我不知道如何解决这个问题。

这是我的代码:(Cell 类和 CollectionViewController 类)

    import UIKit

private let reuseIdentifier = "Cell"

class myCollectionViewController: UICollectionViewController {

    @IBOutlet var myCollectionView: UICollectionView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewDidAppear(_ animated: Bool) {
        myCollectionView.reloadData()
    }

    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }


    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 7
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! myCollectionViewCell
    
        if(indexPath.item != 0){
            cell.setProgress(progress: 1 / Double(indexPath.item))
        }
        return cell
    }
    
    override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! myCollectionViewCell
        cell.setProgress(progress: cell.getProgress() + 0.1)
        myCollectionView.reloadData()
    }
}



import UIKit
import MKRingProgressView

class myCollectionViewCell: UICollectionViewCell {
    @IBOutlet weak var ringView: UIView!
    let ringsize = 150
    var ringProgressView = RingProgressView()
    override func layoutSubviews() {
         ringProgressView = RingProgressView(frame: CGRect(x: 0, y: 0, width: ringsize, height: ringsize))
        ringProgressView.startColor = .red
        ringProgressView.endColor = .magenta
        ringProgressView.ringWidth = CGFloat(ringsize) * 0.15
        ringProgressView.progress = 0.0
        ringProgressView.shadowOpacity = 0.5
        ringView.addSubview(ringProgressView)
    }
}

extension myCollectionViewCell{
    func setProgress(progress: Double){
        UIView.animate(withDuration: 0.5){
            self.ringProgressView.progress = progress
        }
    }
    func getProgress() -> Double{
        return self.ringProgressView.progress
    }
}

这是启动时的样子(在 (1/indexpath.item) 处测试的进度:

这就是我点击底部左侧圆圈 1 次时的样子:

我可以通过动画看到,第二个环以相同的进度覆盖在左下圆圈的第一个环上。不知何故,其他戒指也发生了变化……为什么?您甚至可以在其他一些圆圈上看到第二个环。您还可以看到红色的阴影变暗了一点。当我多次点击时,一切都变得完全(强烈)红色。

感谢您的帮助!

【问题讨论】:

    标签: ios swift xcode uicollectionview uicollectionviewcell


    【解决方案1】:

    简单用法:

        override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            let cell = collectionView.cellForItem(at: indexPath) as! myCollectionViewCell
            cell.setProgress(progress: cell.getProgress() + 0.1)
        }
    

    你不应该这样打电话:

        override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! myCollectionViewCell
            cell.setProgress(progress: cell.getProgress() + 0.1)
            myCollectionView.reloadData()
        }
    

    由于单元重用机制,

    你打电话

    collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! myCollectionViewCell
    

    你会得到一个对象池的单元格,即一个新创建的单元格,或者一个已创建但不可见的单元格


    myCollectionView.reloadData()
    

    更糟糕的是,调用这个,只是做重置,

    因为您不维护数据。

    【讨论】:

      【解决方案2】:

      您可以使用模式标记和配置

      在方法didSelectItemAt 中,更新数据

      cellForItemAt 方法中,更新UI,使用 myCollectionView.reloadData()触发

        var progressData = [IndexPath: Double]()
      
        override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
              let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! myCollectionViewCell
          
              
              if let val = progressData[indexPath]{
                   cell.setProgress(progress: val)
              }
              else{
                   var value = Double(0)
                   if(indexPath.item != 0){
                       value = 1 / Double(indexPath.item)
                   }
                   
                   progressData[indexPath] = value
                   cell.setProgress(progress: value)
              }
              
              return cell
          }
          
          override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
              progressData[indexPath]! += 0.1
              myCollectionView.reloadData()
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-11
        • 2022-12-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-29
        相关资源
        最近更新 更多