集合查看Cell Circle Loader影响多个单元格和闪烁

时间:2015-04-16 16:00:50

标签: ios swift uiviewanimation collectionview

我有一个基本上是书库的视图,我一直在尝试为书籍添加循环加载动画,以便用户在选择新书时可以看到下载进度。我遇到的问题是加载动画在indexPath 0-0的单元格中工作正常,但是当它在任何其他indexPath中时,动画将闪烁并暂时出现在其他单元格上。

在下图中,我正在下载日语,但是装载程序暂时在阿尔巴尼亚语,亚美尼亚语,Cebuano以及此屏幕截图时未捕获的其他几本书中闪烁。因为日本装载机也在闪烁,我拍摄截图的那一刻根本没有显示日本装载机。

Bug

经过一些调试后,我发现这很有可能发生,因为每次重新加载视图时,单元格都会被重用,并且由于某种原因,单元格的顺序会被循环。我已尝试覆盖自定义单元格上的prepareForReuse并将设置重新设置为隐藏,但我仍然会在一瞬间获得进度重影,导致闪烁。

我执行进度指示器的代码非常基本。下面是我的设置功能,它在单元初始化时创建进度条

func setupProgressCircle(){
        progressCircle = CAShapeLayer();

        let centerPoint = CGPoint (x: bookView.bounds.width / 2, y: bookView.bounds.height / 2);
        let circleRadius : CGFloat = bookView.bounds.width / 2 * 0.5;

        var circlePath = UIBezierPath(arcCenter: centerPoint, radius: circleRadius, startAngle: CGFloat(-0.5 * M_PI), endAngle: CGFloat(1.5 * M_PI), clockwise: true    );

        progressCircle = CAShapeLayer ();
        progressCircle!.path = circlePath.CGPath;
        progressCircle!.strokeColor = UIColor.whiteColor().CGColor;
        progressCircle!.fillColor = UIColor.clearColor().CGColor;
        progressCircle!.lineWidth = 5;
        progressCircle!.strokeStart = 0;
        progressCircle!.strokeEnd = 0
        overlayView.layer.addSublayer(progressCircle);
    }

随着下载的进行,我会从cellForRowAtIndexPath调用以下函数来增加进度。

func setProgress(progress: CGFloat){
    progressCircle?.strokeEnd = progress
}

我已经添加了以下函数,以便在单元格被重用或重新排序时,进度将默认为无效且无指示。

override func prepareForReuse() {
        if progressCircle != nil{
            progressCircle?.hidden = true
            progressCircle!.strokeEnd = 0
        }
    }

不幸的是,我所尝试的任何事情都没有解决这个问题。目前,每当我在图书上获得进度更新时,我都会致电collectionView.reloadData(),我想知道这是否可能是问题的一部分。

我可以接受重构,我不是专家,很可能会把问题接近错误。我对建议持开放态度,可以根据需要进行详细说明。谢谢!

更新

根据要求,这是我的cellForRowAtIndexPath

的精简版本
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionCell", forIndexPath: indexPath) as! LanguageBookCell
    var book = controller.objectAtIndexPath(indexPath) as! BookData

    ...Cell Text/Image/Config...

    if(book.active == false){
        cell.overlayView!.alpha = 0.7
        cell.dlLabel.hidden = false
        cell.dlLabel.text = "Tap to Download"
        cell.progressCircle.hidden = true
    }else if(book.status == "Loading"){
        cell.progressCircle.hidden = false
        cell.setProgress(percentLoaded)
    }
    ... Other Cell Configs...

    return cell
}

1 个答案:

答案 0 :(得分:1)

根据要求,我发布了我能够提出的最佳解决方案。

我无法弄清楚如何强迫细胞不重新排序,无论我尝试什么,每次调用reloadData()时,细胞都会重新排序。

然而,当我意识到其他属性也被移动时,例如标题,我能够阻止我的细胞闪烁。

最后,我发现我只是重新计算了更改的单元格的进度,所以当单元格迁移时,它们不会重置为正确的属性。通过始终将单元格设置重置为我的cellForRowAtIndexPath内的默认设置,我能够摆脱闪烁。

对于那些遇到类似问题的人,我最好的建议是仔细检查你的逻辑语句,以确保你的代码中没有空洞,如果单元格被重新分配,设置不会被重置正常。祝大家好运!