Bartłomiej Semańczyk
Bartłomiej Semańczyk

Reputation: 61840

Async image loading after some actions on this image - image changes to wrong image while scrolling

I know that there is similar question: Async image loading from url inside a UITableView cell - image changes to wrong image while scrolling

But I do not only load images from URL. I have them, perform some actions on them, and then assign them to UIImageView WITHIN UITableViewCell.

This is how I do this:

  1. Within cellForRowAtIndexPath:

    cell.configureCellWithComment(comment)
    
  2. These are methods inside my cell:

    func configureCellWithComment(comment: WLComment) {
    
        if let attachmentUrl = comment.attachmentUrl, let fileName = NSURL(string: attachmentUrl)?.lastPathComponent {
    
            if !NSFileManager.defaultManager().fileExistsAtPath(comment.destinationPathForAttachment().URLByAppendingPathComponent(fileName).path!) {
    
                WLFileClient.sharedClient().downloadFileFrom(attachmentUrl, destinationPath: comment.destinationPathForAttachment(), fileName: fileName, progress: nil, completionBlock: { error in
                    self.attachImageToImageView()
                })
            } else {
                attachImageToImageView()
            }
        }
    }
    

Private method:

private func attachImageToImageView() {

    if let attachmentUrl = comment.attachmentUrl, let fileName = NSURL(string: attachmentUrl)?.lastPathComponent {

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {

            let image = WLFileClient.sharedClient().previewImageForFileAtUrl(self.comment.destinationPathForAttachment().URLByAppendingPathComponent(fileName))

            dispatch_async(dispatch_get_main_queue(), {
                self.previewAttachmentButton.enabled = true
                self.attachmentPreviewImageView.image = image
            });
        });
    }
}

What should I do to fix this?

Upvotes: 1

Views: 74

Answers (1)

ShahiM
ShahiM

Reputation: 3268

your downloadFileFrom is an asyc method. so by the time this task completes, the cell may have been reused for another row. so before you call self.attachImageToImageView(), check if the current cell is serving the same row as it was when the method started.

in cellForRowAtIndexPath, set the tag of the cell to the current row number.

cell.tag = indexPath.row

Now in your configureCellWithComment method, first store the tag into a variable and then check if the variable is still the same after the async task:

var tagCache:int = self.tag;

WLFileClient.sharedClient().downloadFileFrom(attachmentUrl, destinationPath: comment.destinationPathForAttachment(), fileName: fileName, progress: nil, completionBlock: {

    if(tagCache==self.tag)
      self.attachImageToImageView()
})

PS: I'm more used to Objective-C, not swift, so forgive syntax mistakes if any.

Upvotes: 1

Related Questions