Collection View Cell Circle Loader 影响多个单元格和闪烁
Collection View Cell Circle Loader affecting multiple cells and flickering
我有一个本质上是图书馆的视图,我一直在尝试向书籍添加循环加载动画,以便用户可以在 select 新书时看到下载进度。我遇到的问题 运行 是加载动画在 indexPath 0-0 的单元格中时工作正常,但当它在任何其他 indexPath 中时,动画将闪烁并暂时出现在其他单元格上。
在下图中,我正在下载日文,但加载程序在阿尔巴尼亚语、亚美尼亚语、宿雾语和其他几本在此屏幕截图时未捕获的书籍上暂时闪烁。因为日版loader也是闪烁的,所以我截图的那一瞬间根本就没有显示日版loader。
经过一些调试后,我发现这很可能发生,因为每次重新加载视图时,单元格都会被重新使用,并且由于某种原因,单元格的顺序会循环。我已经尝试覆盖自定义单元格上的 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
}
根据要求,我发布了我能想到的最佳解决方案。
我一直无法弄清楚如何强制单元格不重新排序,无论我尝试了什么,每次调用 reloadData()
时,单元格都会重新排序。
然而,当我意识到其他属性(例如标题)也被移动时,我能够阻止我的单元格闪烁。
最后,我发现我只是重新计算发生变化的单元格的进度,因此当单元格四处移动时,它们不会重置为正确的属性。通过始终将单元格设置重置为 cellForRowAtIndexPath
中的默认值,我能够消除闪烁。
对于那些遇到类似问题的人,我最好的建议是仔细检查您的逻辑语句,以确保您的代码中没有漏洞,如果单元格被重新分配,设置将无法正确重置.祝大家好运!
我有一个本质上是图书馆的视图,我一直在尝试向书籍添加循环加载动画,以便用户可以在 select 新书时看到下载进度。我遇到的问题 运行 是加载动画在 indexPath 0-0 的单元格中时工作正常,但当它在任何其他 indexPath 中时,动画将闪烁并暂时出现在其他单元格上。
在下图中,我正在下载日文,但加载程序在阿尔巴尼亚语、亚美尼亚语、宿雾语和其他几本在此屏幕截图时未捕获的书籍上暂时闪烁。因为日版loader也是闪烁的,所以我截图的那一瞬间根本就没有显示日版loader。
经过一些调试后,我发现这很可能发生,因为每次重新加载视图时,单元格都会被重新使用,并且由于某种原因,单元格的顺序会循环。我已经尝试覆盖自定义单元格上的 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
}
根据要求,我发布了我能想到的最佳解决方案。
我一直无法弄清楚如何强制单元格不重新排序,无论我尝试了什么,每次调用 reloadData()
时,单元格都会重新排序。
然而,当我意识到其他属性(例如标题)也被移动时,我能够阻止我的单元格闪烁。
最后,我发现我只是重新计算发生变化的单元格的进度,因此当单元格四处移动时,它们不会重置为正确的属性。通过始终将单元格设置重置为 cellForRowAtIndexPath
中的默认值,我能够消除闪烁。
对于那些遇到类似问题的人,我最好的建议是仔细检查您的逻辑语句,以确保您的代码中没有漏洞,如果单元格被重新分配,设置将无法正确重置.祝大家好运!