Swift: UICollectionView 图像加载
Swift: UICollectionView images loading
我有问题。由于单元格中图像的大小,我的 UICollectionView 的滚动速度太慢。图像的调整大小功能几乎没有任何变化。由于图像的数量,我无法制作图像的小副本。
那么如果我需要像在原生相册应用程序中一样快速加载图像,我该怎么办?我听说过 "lazy loading",但我在 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
如果你能帮我解决这个问题,我会很高兴!
PS 应用程序无法从 Web 加载它。所有图像都在设备上的应用程序中。
更新
终于实现了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
这是因为你是在主线程中加载图片,最好在后台线程中加载,这样更流畅,最好在后台线程中解码图片。你将直接设置图像 当你将图像设置为 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
})
你为什么不使用:
let name = (painting.valueForKey("imageName") as? String)!
cell.imageView.image = UIImage(named: name)
而不是使用 NSBundle
因为使用名称方法加载图像缓存图像
我有问题。由于单元格中图像的大小,我的 UICollectionView 的滚动速度太慢。图像的调整大小功能几乎没有任何变化。由于图像的数量,我无法制作图像的小副本。 那么如果我需要像在原生相册应用程序中一样快速加载图像,我该怎么办?我听说过 "lazy loading",但我在 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
如果你能帮我解决这个问题,我会很高兴! PS 应用程序无法从 Web 加载它。所有图像都在设备上的应用程序中。
更新
终于实现了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
这是因为你是在主线程中加载图片,最好在后台线程中加载,这样更流畅,最好在后台线程中解码图片。你将直接设置图像 当你将图像设置为 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
})
你为什么不使用:
let name = (painting.valueForKey("imageName") as? String)!
cell.imageView.image = UIImage(named: name)
而不是使用 NSBundle
因为使用名称方法加载图像缓存图像