简体   繁体   English

使用Parse.com和Swift在tableView中异步加载图片

[英]Async image loading in tableView using Parse.com and swift

I have an app like instagram that display photos in a tableView. 我有一个像instagram这样的应用程序,可以在tableView中显示照片。 When the network is slow, image are re used in wrong cells and my dowload indicator label is also reused in wrong cells as i scroll fast. 当网络很慢时,在错误的单元格中会重新使用图像,并且在我快速滚动时,错误的单元格中也会重新使用我的下载指示器标签。

I tried to use async image loading but can't optimize it. 我尝试使用异步图像加载,但无法对其进行优化。

Here is my cellForRowAtIndexPath method : 这是我的cellForRowAtIndexPath方法:

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

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

    if indexPath.section == timeLineData.count - 1 {
        println("load more pics")
        loadPost()
    }

    cell.tag = indexPath.row


    // timeLineData is my data array

    if timeLineData.count != 0 {

        let userPost  = timeLineData.objectAtIndex(indexPath.section) as PFObject

        cell.commentButton.tag = indexPath.section

    // check if image is in the cache

     if let imagePostedCache: AnyObject = self.imageCache.objectForKey(userPost.objectId){

        dispatch_async(dispatch_get_main_queue(), {
            if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) as? WallTableViewCell {
                cell.imagePosted.image = imagePostedCache as? UIImage
                cell.downloadProgressLabel.hidden = true
            }
        })

    }

        // if it is not in the cache get the image from Parse

    else if  let imagesPost:PFFile = userPost["imageFile"] as? PFFile  {
        cell.imagePosted.image = nil
        cell.downloadProgressLabel.hidden = false



        imagesPost.getDataInBackgroundWithBlock({ (imageData:NSData!, error :NSError!) -> Void in

            if !(error != nil) {

                let image:UIImage = UIImage(data: imageData)!

                // add image to the cache

                self.imageCache.setObject( image , forKey: userPost.objectId)

                // display image in the cell

                dispatch_async(dispatch_get_main_queue(), {
                 if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) as? WallTableViewCell {
                        cell.imagePosted.image = image as UIImage
                    }
                })


            }

            else {
                println("error")
            }

            }, progressBlock: { (progressStatus :Int32) -> Void in

               cell.downloadProgressLabel.text = "\(progressStatus) %"

                if progressStatus == 100 {

                    cell.downloadProgressLabel.text = ""
                }
        })

        }

    // Define description

        if cell.tag == indexPath.row {

    cell.brandLabel.text = userPost["photoText"] as? String
        }
    }


    return cell
}

Here is my custom cell : 这是我的自定义单元格:

    import UIKit
  import QuartzCore

 class WallTableViewCell: UITableViewCell {



@IBOutlet var downloadProgressLabel: UILabel!

@IBOutlet var commentButton: UIButton!

@IBOutlet var imagePosted: UIImageView!


@IBOutlet var brandLabel: UILabel!


}

WallTableViewCell WallTableViewCell

import UIKit
import QuartzCore

class WallTableViewCell: UITableViewCell 
{
    var isDownloadingInProgress
    @IBOutlet var downloadProgressLabel: UILabel!
    @IBOutlet var commentButton: UIButton!
    @IBOutlet var imagePosted: UIImageView!
    @IBOutlet var brandLabel: UILabel!

    func updateCellWithUserPost(userPost: PFObject)
    {
        if let imagePostedCache: AnyObject = self.imageCache.objectForKey(userPost.objectId)
        {
            self.imagePosted.image = imagePostedCache as? UIImage
            self.downloadProgressLabel.hidden = true
        }
        else if let imagesPost:PFFile = userPost["imageFile"] as? PFFile  
        {
            self.imagePosted.image = nil
            self.downloadProgressLabel.hidden = false
            isDownloadingInProgress = true

            imagesPost.getDataInBackgroundWithBlock({ (imageData:NSData!, error :NSError!) -> Void in
                isDownloadingInProgress = false
                if !(error != nil) 
                {
                    let image:UIImage = UIImage(data: imageData)!
                    self.imageCache.setObject( image , forKey: userPost.objectId)
                    self.imagePosted.image = image as UIImage
                }
                else 
                {
                    println("Error while downloading image")
                }
            }, progressBlock: { (progressStatus :Int32) -> Void in
                    self.downloadProgressLabel.text = "\(progressStatus) %"
                    if progressStatus == 100 
                    {
                        cell.downloadProgressLabel.text = ""
                    }
            })
        }
    }
}

cellForRowAtIndexPath method cellForRowAtIndexPath方法

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
{
    let cell:WallTableViewCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as WallTableViewCell
    let userPost  = timeLineData.objectAtIndex(indexPath.section) as PFObject
    if (!cell.isDownloadingInProgress)
        cell.updateCellWithUserPost(userPost)

    return cell
}

Note: I don't know Swift too much as I am a pure Objective-C programmer. 注意:我不太了解Swift,因为我是纯粹的Objective-C程序员。 Let me know if you have any questions regarding the answer 如果您对答案有任何疑问,请告诉我

Try using SDWebImages . 尝试使用SDWebImages。 It will handle images for your application properly . 它将为您的应用程序正确处理图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM