AFNetworking setImageWithURLRequest sets image in wrong cell after scrolling (iOS, Swift)

I am using a table with dequeueReusableCellWithIdentifier

and afnetworking+uiimageview

. Some of my cells have images and some don't. If I loop through the table before loading the image, the success block will put the image in a reusable, wrong cell. For example, the image was in cell # 2, but after scrolling, it appeared in cell # 8, because at that moment the figure eight took second place. Can be used setImageWithURLRequest

together with dequeueReusableCellWithIdentifier

?

My code:

    let cell = tableView.dequeueReusableCellWithIdentifier("simpleCell", forIndexPath: indexPath) as UITableViewCell!
    cell.textLabel.text = fields[indexPath.row]["name"] as String
    cell.imageView.image = nil
    if let image = fields[indexPath.row]["image"] as? String {
        if (image != "") {
            let image_url = NSURL(string: image)
            let url_request = NSURLRequest(URL: image_url)
            let placeholder = UIImage(named: "no_photo")
            cell.imageView.setImageWithURLRequest(url_request, placeholderImage: placeholder, success: { [weak cell] (request:NSURLRequest!,response:NSHTTPURLResponse!, image:UIImage!) -> Void in
                if let cell_for_image = cell {
                    cell_for_image.imageView.image = image
                    cell_for_image.setNeedsLayout()
                }
            }, failure: { [weak cell]
               (request:NSURLRequest!,response:NSHTTPURLResponse!, error:NSError!) -> Void in
                if let cell_for_image = cell {
                    cell_for_image.imageView.image = nil
                    cell_for_image.setNeedsLayout()
                }
            })
        }
    }
    return cell

      

Sorry if my question duplicates another. I have found many similar questions, but I have not found a solution. I tried to add reload

tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)

      

into my block of success, but it doesn't help.

UPDATE: I also noticed that I don't have this problem in cases where all of my cells have images. If I understand correctly, the reason is this: AFNetworking aborts the previous request for the same cell when trying to request a new image. But if I have no image in the cell, it will not be interrupted. How can I do this manually?

+3


source to share


2 answers


When a cell is reused by a table view, the image loading is still processed in the background. When finished, it cell

points to a reusable cell with different content.

You have two options:



  • Calling cancelImageRequestOperation

    in image view aftercell.imageView.image = nil

  • In the completion handler, do not reference cell

    ; instead use your data model to query for the correct cell from your table view.
+4


source


Check if a cell is visible



let visibleCells = tableView.visibleCells as NSArray
cell.imageView.setImageWithURLRequest(url_request, placeholderImage: placeholder, success: { [weak cell] (request:NSURLRequest!,response:NSHTTPURLResponse!, image:UIImage!) -> Void in
                if let cell_for_image = cell {
                    if(visibleCells.containsObject(cell)) {
                      cell_for_image.imageView.image = image
                      cell_for_image.setNeedsLayout()
                    }

                }
            }, failure: { [weak cell]
               (request:NSURLRequest!,response:NSHTTPURLResponse!, error:NSError!) -> Void in
                if let cell_for_image = cell {
                    cell_for_image.imageView.image = nil
                    cell_for_image.setNeedsLayout()
                }
            })

      

0


source







All Articles