UITablViewCell Not Updating when seccess block called
danwetherald opened this issue · 9 comments
I am not seeing the image pop in as soon as the println() I have in the success block getting called. Would this be an issue only because its a UITableViewCell? It will eventually show the image, but its like 5-8 seconds later, Im guessing this is a built in double check timeout? But I would think it would pop in as soon as that println() gets called. If i stretch the table down do that the last imageview is off and then back on the screen i will see the image but will still have the activity loader showing meaning the success block didn't finish.
var profileImageUrl:String = "" {
didSet {
//fetch the image
ImageManager.fetch(profileImageUrl,
progress: { (status: Double) in
println("\(status)")
self.ProfileImageLoading.startAnimating()
},success: { (data: NSData) in
println("got image")
self.ProfileImage.image = UIImage(data: data) //set the image data
self.ProfileImage.backgroundColor = UIColor.clearColor()
self.ProfileImageLoading.stopAnimating()
}, failure: { (error: NSError) in
self.ProfileImageLoading.stopAnimating()
})
}
}
Thanks,
Dan
I don't know enough about your implementation to know exactly what is wrong, but it is probably the way the didSet is configured with the UITableViewCell recycling logic. didSet
only gets called after the profileImageUrl
gets modified. The UITableViewCell will be recycled and reused by the tableview as scrolling happens. It is probably the case that the ProfileImageLoading
activity indicator is started when a cell gets setup and the profileImageUrl didSet
isn't called again to update the current ProfileImage
image view. The images get cached automatically so that is probably why the show up after the 5-8 seconds. The tableView gets scrolled up and down and the image is already available, so it gets displayed immediately.
That is the latest implementation that I have tried, originally all that code was just in the cellForRowAtIndexPath method and it had the exact same behavior... would that make a difference?
I can't say for certain without seeing all the code, but probably not. The cellForRowAtIndexPath
method is the place where cells get reused, but if the code is structured the same way it would produce the same result. Your basic setup would be something like so:
- Model objects that store which Url to load, text to display, etc. They each represent a different row in the TableView.
- UITableViewCell (or custom subclass of one) that has the the views that will be updated by the model objects
- Inside
cellForRowAtIndexPath
you update the TableViewCell with the data from the correct model for that row. This would include theImageManager.fetch
call.
That basic model should make the images show up properly.
It was also just brought to my attention that the image assignment wasn't being done on the main thread. Also try doing this:
dispatch_async(dispatch_get_main_queue(), {
self.ProfileImage.image = UIImage(data: data) //set the image data
})
You know what, scratch that last comment. I decided to just update Skeets to return on the main thread. Just update Skeets code to the latest and should be good to go.
I was about to check in on this issue and mention the mainThread issue but you have already taken care of that. Nicely done mate!
👍 Shocked it took me this long to notice 😄. Just trying to be proactive!
@dan003400 did you try the latest code? Did it seem to fix the issue?
I am going to assume this one is fixed. We can reopen the issue if it comes up again.