Swift Async Imageloader

时间:2015-08-19 13:00:31

标签: ios swift uitableview

我想用显示图像的单元格实现tableview。图像将异步加载。为了更好地滚动,我想要在单元格滚出视图时取消请求。 我的代码到目前为止有效,但我不知道如何检测单元格是否可见或已经滚动过#34;

这是我的代码:

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("EventsTableCell", forIndexPath: indexPath) as! EventsTableCell
    var elem : Event = data[indexPath.row] as Event

    cell.headlineLabel.text = elem.getName()
    cell.secondLabel.text = elem.getDescription()

    cell.progressView.setProgress(0.0,animated: true)

    if let image = ImageCache.getImage(elem.getId()) {
        cell.coverImage.image = image
        cell.progressView.removeFromSuperview()
    } else {
        cell.coverImage.image = UIImage(named: "loading")
        if(elem.getCover() == nil){
            //NOIMAGE
            cell.progressView.removeFromSuperview()
        }else{
            println("start request for" + elem.getName()!)
            cell.request = Alamofire.request(.GET, elem.getCover()!)
                .progress {
                    (_, totalBytesRead, totalBytesExpectedToRead) in

                    dispatch_async(dispatch_get_main_queue()) {
                        // 6
                        cell.progressView.setProgress(Float(totalBytesRead) / Float(totalBytesExpectedToRead), animated: true)

                        // 7
                        if totalBytesRead == totalBytesExpectedToRead {
                            cell.progressView.removeFromSuperview()
                        }
                    }
                }
                .response { (request, response, data, error) in
                    if error == nil && cell.coverImage.image != nil {
                        ImageCache.addImage(elem.getId(),image: UIImage(data: data!, scale:1)!)
                        cell.coverImage.image = UIImage(data: data!, scale:1)
                    }else{

                    }
            }
        }
    }
    return cell
}

使用以下代码我可以取消请求:

cell.request!.cancel()

我还注意到progressView有时没有显示,或者可能会从superview中删除到早期,也许有人可以提供帮助。

由于 托拜厄斯

2 个答案:

答案 0 :(得分:3)

  

为了更好地滚动,我希望在单元格滚出视图时取消请求。

实施tableView:didEndDisplayingCell:forRowAtIndexPath:,并在其中取消此行的下载。这正是这种委托方法的用途!

答案 1 :(得分:1)

出于性能原因,表格视图会重复使用单元格。因此,对于不同的indexPath,可以将相同的单元用于大量时间。

以下行

tableView.dequeueReusableCellWithIdentifier("EventsTableCell", forIndexPath: indexPath) as! EventsTableCell 

只有在没有人可以重用时才会创建一个新的EventsTableCell对象!

所以现在progressView问题很明显 - 您可以通过调用

将其从单元格中删除
cell.progressView.removeFromSuperview()

但你永远不会添加它。例如,您可以在dequeueReusableCellWithIdentifier调用后立即添加它,如果需要,可以稍后删除。我认为在你的情况下,最好不要删除/添加它,而是隐藏/显示:

cell.progressView.hidden = false

图像请求完全相同 - 您可以调用

cell.request?.cancel()

dequeueReusableCellWithIdentifier

之后

为了使您的代码更加明显,您可以在EventsTableCell的prepareForReuse方法中取消,但它会产生相同的效果。

  

<强> prepareForReuse

     

准备一个可重用的单元格,供表视图的委托重用。