图像在 UITableViewCell 中不按顺序显示

Images not show in sequence in UITableViewCell

我正在尝试将 XML enclosure 中的图像显示到 tableViewCell 图像。由于 dequeueReusableCellWithIdentifier,图像显示但不按顺序显示,因为当我上下滚动 tableViewCell 时,它会更改图像而不按顺序显示 array index。我尝试了不同的方法,但没有成功'
谁能告诉我如何按顺序显示图像,或者有什么方法可以先下载所有图像然后在单元格图像中显示? 或任何其他快速或简单的方法,而不是使用 dispatch_async。 谢谢

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell : ImageCell2 = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ImageCell2

        cell.titleLabel.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as! NSString as String

        downloadFileFromURL(NSURL(string: self.posts.objectAtIndex(indexPath.row).valueForKey("enclosure") as! String)!, completionHandler:{(img) in
            dispatch_async(dispatch_get_main_queue(), { () -> Void in

                cell.sideImageView.image = img

                })
            })

        return cell

    }

UPDATE

现在我尝试了这个

let picURL = self.posts.objectAtIndex(indexPath.row).valueForKey("enclosure") as! String
let url = NSURL(string: picURL)
let data = NSData(contentsOfURL: url!)

cell.sideImageView?.image = UIImage(data: data!)

它按顺序显示图像,但很难滚动?

Update2

现在我试过了

var check = true
var imageArrayNsData : [NSData] = []

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

let cell : ImageCell2 = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ImageCell2

cell.titleLabel.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as! NSString as String

if check == true{
            var indeX = 0
            for i in posts.valueForKey("enclosure") as! [NSString]{
                let picURL = self.posts.objectAtIndex(indeX).valueForKey("enclosure") as! String
                let url = NSURL(string: picURL)
                let data = NSData(contentsOfURL: url!)
                print("download")
                imageArrayNsData.append(data!)
                indeX++
                print(indeX)
            }
            check = false
        }

if check == false{
        cell.sideImageView.image = UIImage(data: imageArrayNsData[indexPath.row])
    }
return cell

}

此方法只下载一次图片。下载图像后,它会附加到数组中,下次它会显示数组中的图像而无需再次下载。但是这种方法对于滚动来说有点困难。有人知道为什么吗?

问题是 cell 对象在您设置图像时可能已经被重新使用。您需要添加一个检查以确保该单元格仍然代表您想要的内容。这可能很简单:

if tableView.indexPathForCell(cell) == indexPath {
    cell.sideImageView.image = img
}

但如果特定项目的索引路径可能在那个时候发生变化(例如,如果用户可以 insert/delete 行),则可能需要更复杂。

您也可以使用像 AlamofireImage 这样的库来为您处理这项工作(以不同的方式)。使用 AlamofireImage,您的代码将如下所示:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell : ImageCell2 = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ImageCell2            
    cell.titleLabel.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as! NSString as String

    let URL = NSURL(string: self.posts.objectAtIndex(indexPath.row).valueForKey("enclosure") as! String)!
    cell.sideImageView.af_setImageWithURL(URL)

    return cell            
}

要异步下载图像并设置为 UITableViewCell 的 UIImageView,您可以向 UIImageView 添加扩展。

extension UIImageView {
    func downloadImageFrom(link link:String, contentMode: UIViewContentMode) {
        //in my methods, I have a cache to avoid re-downloading my images. Images in cache are identified by its URL
        if let _imageData = ImageCache.shareCache.getImageData(link) {
            self.image = UIImage(data: _imageData)
            return
        }

        //else, download image
        NSURLSession.sharedSession().dataTaskWithURL( NSURL(string:link)!, completionHandler: {
            (data, response, error) -> Void in
            dispatch_async(dispatch_get_main_queue()) {
                self.contentMode =  contentMode
                if let data = data {
                    ImageCache.shareCache.cacheImageData(data, imageId: link)
                    self.image = UIImage(data: data)
                }
            }
        }).resume()
    }
}

然后,根据您的回电 cellforrow

let cell : ImageCell2 = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ImageCell2

cell.titleLabel.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as! NSString as String

cell.imageView.downloadImageFrom(yourImageUrl)
return cell