将图像从URL加载到表格视图单元格中的图像视图的更快方法

时间:2015-03-06 18:50:37

标签: ios xcode swift

我使用它将URL加载到图像视图

let url = NSURL(string: URL)
let data = NSData(contentsOfURL: url!)
self.releasephoto.image  = UIImage(data: data!)

但是当表视图单元格中有10个项目具有不同的图像时,滚动会变慢并挂起

我加载大小为40 X 40的图像

我想知道是否有更好的方法来加载网址图片?

5 个答案:

答案 0 :(得分:21)

我建议使用SDWebImage

安装完成后,您需要为Swift制作一个桥接标题并包含以下行:

#import "UIImageView+WebCache.h"

然后你需要在你的cellForRowAtIndexPath函数中做的就是:

let url = NSURL(string: URL)
self.releasephoto.sd_setImageWithURL(url)

这个库的好处在于它会自动缓存图像,因此只下载一次。

答案 1 :(得分:5)

您必须异步加载视图。最初提供虚拟或空白图像。然后在后台异步加载到模型中,显示当前显示的单元格的任何图像。当每个图像到达时,将其存储在模型中并重新加载表视图。因此,每个图像都会在到达时出现,但是你的滚动不会因为总是 一个图像而变慢 - 如果你还没有为这一行提取图像,则为空白或虚拟,如果你拿到了它,还是真实的图像。

以下是我书中的示例代码:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath:indexPath) as UITableViewCell
    let m = self.model[indexPath.row]
    cell.textLabel!.text = m.text
    // have we got a picture?
    if let im = m.im {
        cell.imageView!.image = im
    } else {
        if m.task == nil { // no task? start one!
            cell.imageView!.image = nil
            m.task = self.downloader.download(m.picurl) { // *
                [weak self] url in // *
                m.task == nil // *
                if url == nil {
                    return
                }
                let data = NSData(contentsOfURL: url)!
                let im = UIImage(data:data)
                m.im = im
                dispatch_async(dispatch_get_main_queue()) {
                    self!.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
                }
            }
        }
    }
    return cell
}

(完整的工作示例为here。而MyDownloader的代码self.downloader的类别为here。)

为了获得额外的超级效率,如果用户在图像到达之前将一行拖出视图,请取消下载。这样就可以设置一次可以进行多少下载的上限。

答案 2 :(得分:5)

我已经回答了类似的问题here

使用以下课程:

class ImageLoadingWithCache {

    var imageCache = [String:UIImage]()

    func getImage(url: String, imageView: UIImageView, defaultImage: String) {
        if let img = imageCache[url] {
            imageView.image = img
        } else {
            let request: NSURLRequest = NSURLRequest(URL: NSURL(string: url)!)
            let mainQueue = NSOperationQueue.mainQueue()

            NSURLConnection.sendAsynchronousRequest(request, queue: mainQueue, completionHandler: { (response, data, error) -> Void in
                if error == nil {
                    let image = UIImage(data: data)
                    self.imageCache[url] = image

                    dispatch_async(dispatch_get_main_queue(), {
                        imageView.image = image
                    })
                }
                else {
                    imageView.image = UIImage(named: defaultImage)
                }
            })
        }
    }
}

用法:

var cache = ImageLoadingWithCache()
cache.getImage(YOUR_URL, imageView: YOUR_IMAGEVIEW, defaultImage: "DEFAULT_IMAGE_NAME")

答案 3 :(得分:0)

Apple有一个示例代码LazyTableImages,尽管它在Objective-C中。就像@Matt所提到的那样,它必须是异步完成的。

答案 4 :(得分:0)

    NSURL *url = [NSURL URLWithString:@"http:url..."];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
UIImage *placeholderImage = [UIImage imageNamed:@"your_placeholder"];

__weak UITableViewCell *weakCell = cell;

[cell.imageView setImageWithURLRequest:request
                      placeholderImage:placeholderImage
                               success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {

                                   weakCell.imageView.image = image;
                                   [weakCell setNeedsLayout];

                               } failure:nil];

AFNetworking 2可以正常使用。