Swift UICollectionViewCell 动画视图在滚动时随机空白

Posted

技术标签:

【中文标题】Swift UICollectionViewCell 动画视图在滚动时随机空白【英文标题】:Swift UICollectionViewCell Animated View Randomly Blank When Scrolling 【发布时间】:2016-09-26 23:32:25 【问题描述】:

我正在尝试使用UICollectionView 来显示一个正方形MyCollectionViewCell,它在UIImageView 中具有动画GIF。

行和部分的设置如下:

override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int 
    return 1


override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
    return 50

我使用SwiftGif 来获取分配给单元格UIImageView 的GIF,如下所示:

let gifs = [UIImage.gifWithName("gif1"), UIImage.gifWithName("gif2"), UIImage.gifWithName("gif3")]

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("gifCell", forIndexPath: indexPath) as! GifCollectionViewCell
    cell.gifImageView.image = gifs[indexPath.item % gifs.count]
    return cell

大多数情况下,一切都很好。但我的问题是,滚动时,有时单元格为空白且没有出现 GIF。在调试过程中,我为单元格添加了一个标签以显示indexPath.item,如您在上面的代码中所见,以确保单元格不会被传递并发现标签将始终显示indexPath,即使单元格不显示 GIF。

我已经使用常规图像进行了测试,如下所示:

let testImages = [UIImage(named: "testImage1"), UIImage(named: "testImage2", UIImage(named: "testImage3")]

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("gifCell", forIndexPath: indexPath) as! GifCollectionViewCell
    cell.gifImageView.image = testImages[indexPath.item % testImages.count]
    return cell

并且没有出现空白单元格。

更奇怪的是,当我最初在 collectionView(...cellForItemAtIndexPath) 中构建 GIF 时,空白单元格也没有遇到任何问题:

let gifNames = ["gif1", "gif2", "gif3"]

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("gifCell", forIndexPath: indexPath) as! GifCollectionViewCell
    let gif = UIImage.gifWithName(gifNames[indexPath.item % gifNames.count])
    cell.gifImageView.image = gif
    return cell

如果不是因为 GIF 构建过程极大地影响了 UICollectionView 的滚动性能,那么这个原始实现本来可以工作的,这迫使我首先改变实现。

我已经确认这不是 SwiftGif 的问题,因为我已经在另一个应用程序中使用动画渲染库和 AnimatedView 代替 MyCollectionViewCell 中的 UIImageView 并显示动画而不是显示动画而不是GIF 和滚动 CollectionView 时单元格随机显示任何内容而不是动画时遇到了同样的问题。

我已经尝试了 *** 解决方案 here 并实现了自定义 UICollectionViewFlowLayout,如下所示:

class MyFlowLayout: UICollectionViewFlowLayout 
    override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? 
        let attributes = super.layoutAttributesForElementsInRect(rect)
        let contentSize = self.collectionViewContentSize()
        let newAttrs = attributes?.filter  $0.frame.maxX <= contentSize.width && $0.frame.maxY <= contentSize.height
        return newAttrs
    

并像这样在viewDidLoad() 中分配它:

self.collectionView?.collectionViewLayout = MyFlowLayout()

MyFlowLayout我也试过:

override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool 
    return true

我还弄乱了各种单元格大小(宽度比高度小 1,高度比宽度小 1 等),并且弄乱了一些部分插入组合,但没有设法找到导致动画视图的问题的根源不出现。

任何帮助将不胜感激。谢谢

【问题讨论】:

【参考方案1】:

我在分配图像之前通过在collectionView(...cellForItemAtIndexPath) 中设置gifImageView.image = nil 解决了这个问题。

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 
            let cell = collectionView.dequeueReusableCellWithReuseIdentifier("gifCell", forIndexPath: indexPath) as! GifCollectionViewCell
    cell.gifImageView.image = nil    // Added this line
    cell.gifImageView.image = gifs[indexPath.item % gifs.count]
    cell.infoLabel.text = String(indexPath.item)
    return cell
 

不确定如何/为什么修复它,但它现在可以工作。

【讨论】:

以上是关于Swift UICollectionViewCell 动画视图在滚动时随机空白的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式创建 UICollectionViewCell

UICollectionView

如何从 UICollectionViewCell 访问 UICollectionView 中 Cell 的 indexPath

Xcode 6 beta 4,UIButton 在collectionviewcell 中不负责

ios开发之-- tableview/collectionview获取当前点击的cell

swift [Swift Notes]在学习Swift #Swift的同时收集笔记