Swift: UICollectionView 图片加载

3

我有一个问题。我的UICollectionView的滚动太卡顿了,因为单元格中的图像大小太大。缩放函数几乎没有改变什么。而且由于图像数量,我无法制作小的副本。

如果我需要像原生相册应用程序一样快速加载图像,我该怎么办?我听说过“懒加载”,但我找不到任何关于Swift的教程。

这是我的cellForItemAtIndexPath:

        let cell : MyCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("MyCell", forIndexPath: indexPath) as! MyCollectionViewCell

        let painting = objs[indexPath.row]
        let name = (painting.valueForKey("imageName") as? String)!
        let path = NSBundle.mainBundle().bundlePath.stringByAppendingString("/\(name)") as NSString

        cell.imageView.image = UIImage(contentsOfFile: path as String)

        cell.layer.shouldRasterize = true
        cell.layer.rasterizationScale = UIScreen.mainScreen().scale

        return cell

如果你能帮我解决这个问题,我将不胜感激! 附注:应用程序无法从网络加载。所有图片都在设备上的应用程序中。

更新

最终,我实现了SDWebImage。这是我找到的最佳解决方案。 以下是我的cellForRowAtIndexPath:

let cell : MyCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("MyCell", forIndexPath: indexPath) as! MyCollectionViewCell
        let block: SDWebImageCompletionBlock! = {(image: UIImage!, error: NSError!, cacheType: SDImageCacheType, imageURL: NSURL!) -> Void in
            //          println(self)
        }
        let path = NSBundle.mainBundle().bundlePath.stringByAppendingString("/\(images[indexPath.row])") as NSString
        let url = NSURL.fileURLWithPath(path as String)
        println(url)

        cell.imageView.sd_setImageWithURL(url, placeholderImage: UIImage(named: "placeholder"), completed: block)

        cell.layer.shouldRasterize = true
        cell.layer.rasterizationScale = UIScreen.mainScreen().scale

        return cell
2个回答

4

由于您正在主线程中加载图像,最好在后台线程上执行此操作,为了使其更加流畅,最好也在后台线程上解码图像。如果直接设置图像,则在将图像设置为imageView时会进行解码,因此最好先对其进行解码,然后再将其设置为imageView.image

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { () -> Void in
                var image = UIImage(contentsOfFile: path as String)
UIGraphicsBeginImageContextWithOptions(image!.size, true, 0);
        image?.drawAtPoint(CGPointZero)
        image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    cell.imageView.image = image
                })

它几乎解决了我的问题,集合视图滚动得更快了,但仍然有点卡顿...我认为原因是图片太大了.. 有什么想法吗? - Ivan Petrov

0

你为什么不使用:

let name = (painting.valueForKey("imageName") as? String)!
cell.imageView.image = UIImage(named: name)

不要使用NSBundle,而是用名称方法加载图像并缓存


我有太多的图片。如果我缓存它,应用程序将占用太多设备内存。而这些图片的第一次加载也会很慢和卡顿... - Ivan Petrov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接