【问题标题】:UICollectionView image flickeringUICollectionView 图像闪烁
【发布时间】:2015-06-18 09:45:26
【问题描述】:

我有一个 UICollectionView 全屏显示单元格(即画廊)。 有时,当滑动新图像时,显示右侧图像以外的图像不到一秒钟,然后图像被更新。 其他时候,会显示错误的图像,但如果您向左和向右滑动(即图像消失并重新出现),则会出现正确的图像。 我不明白这种行为的原因。 当集合视图需要图像时,图像会异步下载。 代码如下:

 let blank = UIImage(named: "blank.png")
 func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
     let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! UICollectionViewCell

    let image = images[indexPath.row]
    if let imageView = cell.viewWithTag(5) as? UIImageView {
        imageView.image = blank
        if let cachedImage = cache.objectForKey(image.url) as? UIImage {
            imageView.image = cachedImage
        } else {
            UIImage.asyncDownloadImageWithUrl(image.url, completionBlock: { (succeded, dimage) -> Void in
                if succeded {
                    self.cache.setObject(dimage!, forKey: image.url)
                    imageView.image = dimage
                } 
            })
        }
    }

    return cell
}

UIImage.asyncDownloadImageWithUrl 在哪里:

extension UIImage {
   static func asyncDownloadImageWithUrl(url: NSURL, completionBlock: (succeeded: Bool, image: UIImage?) -> Void) {
       let request = NSMutableURLRequest(URL: url)
       NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: { (response, data, error) in
           if error == nil {
               if let image = UIImage(data: data) {
                  completionBlock(succeeded: true, image: image)
               }
           } else {
                  completionBlock(succeeded: false, image: nil)
           }

       })
     }
  }

对于显示的第一张图片:

func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
    if let index = self.index {
        let newIndexPath = NSIndexPath(forItem: index, inSection: 0)
        self.collectionView.scrollToItemAtIndexPath(newIndexPath, atScrollPosition: UICollectionViewScrollPosition.Left, animated: false)
        self.index = nil
    }
}

【问题讨论】:

    标签: swift uicollectionview


    【解决方案1】:

    这就是我认为正在发生的事情:

    • 单元格 A 出现
    • 请求将图像 A 加载到单元格 A
    • 单元格 A 从屏幕上消失
    • 单元 A 重新出现(被重复使用)
    • 请求将图像 B 加载到单元格 A
    • 对图像 A 的请求已完成
    • 图像 A 加载到单元格 A
    • 对图像 B 的请求已完成
    • 图像 B 加载到单元格 A

    发生这种情况是因为您没有跟踪应在完成块上加载哪个图像 url。

    试试这个:

    一种方法是将图片的网址存储在您的UICollectionViewCell 中。为此,请创建一个子类:

    class CustomCollectionViewCell:UICollectionViewCell {
        var urlString = ""
    }
    

    然后:

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! CustomCollectionViewCell
    
        let image = images[indexPath.row]
        if let imageView = cell.viewWithTag(5) as? UIImageView {
            imageView.image = blank
            cell.urlString = image.url.absoluteString
            if let cachedImage = cache.objectForKey(image.url) as? UIImage {
                imageView.image = cachedImage
            } else {
                UIImage.asyncDownloadImageWithUrl(image.url, completionBlock: { (succeded, dimage) -> Void in
                    if succeded {
                        self.cache.setObject(dimage!, forKey: image.url)
                        //
                        // This can happen after the cell has dissapeared and reused!
                        // check that the image.url matches what is supposed to be in the cell at that time !!!
                        //
                        if cell.urlString == image.url.absoluteString {
                            imageView.image = dimage
                        }
    
                    } 
                })
            }
        }
    
        return cell
    }
    

    如需更准确的回复,请发布项目(或其准系统版本)。重现您的设置和测试需要大量工作。

    【讨论】:

    • 这似乎有效。我必须弄清楚为什么^-^谢谢
    • 很高兴听到!就像我说的那样,这一切都与一个请求可能需要一段时间才能完成的事实有关,与此同时,UICollectionView 可以重用相同的UICollectionViewCell 来显示不同的内容。异步网络调用无法保证执行顺序!你能把答案标记为正确的吗?这样问题就不会显示为“未回答”。
    猜你喜欢
    • 1970-01-01
    • 2012-08-22
    • 2015-04-25
    • 2012-05-13
    • 2010-10-29
    • 1970-01-01
    • 2023-04-02
    • 2011-11-03
    • 1970-01-01
    相关资源
    最近更新 更多