Ios 停止在tableview中同步加载图像

Ios 停止在tableview中同步加载图像,ios,swift,uitableview,swift3,rss,Ios,Swift,Uitableview,Swift3,Rss,我有一个rss订阅源。我在滚动tableview时遇到问题。每当我向下滚动时,标签文本会改变,但图像会在一段时间后改变。在短短的几秒钟内,我可以看到该行的前一张图像。我想看到一个默认的图像,如果它是在后端加载 用于在其演示中获得此延迟加载的代码是: func loadImageSynchronouslyFromURLString(_ urlString: String) -> UIImage? { if let url = URL(string: urlString) {

我有一个rss订阅源。我在滚动tableview时遇到问题。每当我向下滚动时,标签文本会改变,但图像会在一段时间后改变。在短短的几秒钟内,我可以看到该行的前一张图像。我想看到一个默认的图像,如果它是在后端加载

用于在其演示中获得此延迟加载的代码是:

func loadImageSynchronouslyFromURLString(_ urlString: String) -> UIImage? {
    if let url = URL(string: urlString) {
        let request = NSMutableURLRequest(url: url)
        request.timeoutInterval = 30.0
        var response: URLResponse?
        let error: NSErrorPointer? = nil
        var data: Data?
        do {
            data = try NSURLConnection.sendSynchronousRequest(request as URLRequest, returning: &response)
        } catch let error1 as NSError {
            error??.pointee = error1
            data = nil
        }
        if (data != nil) {
            return UIImage(data: data!)
        }
    }
    return nil
}
下面是调用此函数的代码:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "FeedItemCell", for: indexPath) as UITableViewCell
        let item = entries![(indexPath as NSIndexPath).row]   
 if let imageView = cell.viewWithTag(1) as? UIImageView {
            if item.mainImage != nil {
                imageView.image = item.mainImage
            } else {
                if item.imageURLsFromDescription == nil || item.imageURLsFromDescription?.count == 0  {
                    item.mainImage = UIImage(named: "roundedDefaultFeed")
                    imageView.image = item.mainImage
                }
                DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async(execute: { () -> Void in
                    for imageURLString in item.imageURLsFromDescription! {
                        if let image = self.loadImageSynchronouslyFromURLString(imageURLString) {
                            item.mainImage = image
                            DispatchQueue.main.async(execute: { () -> Void in
                                imageView.image = image
                                self.tableView.reloadRows(at: [indexPath], with: .automatic)
                            })
                            break;
                        }
                    }
                })
            }
        }
    return cell
}

请告诉我如何在滚动后加载pic时显示空格。

UITableViewCell
通过避免单元格实例化来提高性能。这就是为什么在下载完成并设置“新”映像之前,您会看到“最后”映像


UITableViewCell
有一个名为
prepareforeuse()
的方法,该方法在重用单元格之前调用

要解决您的问题,请执行以下操作:

子类
UITableViewCell
并重写
prepareforeuse()
和(重新)使用占位符图像设置图像

或:

cellForRowAt:indexPath中设置占位符图像:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "FeedItemCell", for: indexPath) as UITableViewCell
    let item = entries![(indexPath as NSIndexPath).row]   
    if let imageView = cell.viewWithTag(1) as? UIImageView {

        imageView = myPlaceholderImage // set the placeholder you want to see while downloading the image

        if item.mainImage != nil {
           ...
           // your original code
        }

    return cell
}

UITableViewCell
s被重用,通过避免单元实例化来提高性能。这就是为什么在下载完成并设置“新”映像之前,您会看到“最后”映像


UITableViewCell
有一个名为
prepareforeuse()
的方法,该方法在重用单元格之前调用

要解决您的问题,请执行以下操作:

子类
UITableViewCell
并重写
prepareforeuse()
和(重新)使用占位符图像设置图像

或:

cellForRowAt:indexPath中设置占位符图像:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "FeedItemCell", for: indexPath) as UITableViewCell
    let item = entries![(indexPath as NSIndexPath).row]   
    if let imageView = cell.viewWithTag(1) as? UIImageView {

        imageView = myPlaceholderImage // set the placeholder you want to see while downloading the image

        if item.mainImage != nil {
           ...
           // your original code
        }

    return cell
}

使用
asyn
加载数据。在您的
imageView
中显示默认图像,直到从服务器收到您的数据。使用第三方类。@the_dahiya_boy您能举个例子吗?@Ronak我不想使用任何其他第三方类。我无法确定要在现有代码中更改什么来停止此操作。请使用
asyn
加载数据。在您的
imageView
中显示默认图像,直到从服务器收到您的数据。使用第三方类。@the_dahiya_boy您能举个例子吗?@Ronak我不想使用任何其他第三方类。我不知道要在现有代码中更改什么来停止此操作。我的答案应该可以修复错误“每当我向下滚动标签文本时,图像会发生更改。在短短几秒钟内,我可以看到该行的前一个图像…”。错误描述没有更改afaics
reloadRows
不应被调用。顺便说一句,我如何在我的视图控制器中使用此prepareForReuse方法?更新了答案。是否有其他方法可以避免调用loadImageSynchronouslyFromURLString()完全?您可以异步下载它,而不是下载synchronized,并将同步调用包装在
DispatchQueue.global.async
中,但这是一样的。你必须下载图像,这确实需要时间。时期为了获得更好的代码,我会将所有图像内容提取到一个独立的函数“downloadImage(对于单元格:UITableViewCell)”。我的答案应该可以修复错误“每当我向下滚动标签文本时,图像会发生变化,但过一会儿图像会发生变化。在短短的几秒钟内,我可以看到该行的前一个图像…”。错误描述没有更改afaics
reloadRows
不应被调用。顺便说一句,我如何在我的视图控制器中使用此prepareForReuse方法?更新了答案。是否有其他方法可以避免调用loadImageSynchronouslyFromURLString()完全?您可以异步下载它,而不是下载synchronized,并将同步调用包装在
DispatchQueue.global.async
中,但这是一样的。你必须下载图像,这确实需要时间。时期为了获得更好的代码,我将把所有图像内容提取到一个独立的函数“downloadImage”(对于cell:UITableViewCell)。