daltoniam / Skeets

Fetch, cache, and display images via HTTP in Swift.
Apache License 2.0
191 stars 21 forks source link

UITablViewCell Not Updating when seccess block called #6

Closed danwetherald closed 9 years ago

danwetherald commented 9 years ago

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

daltoniam commented 9 years ago

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.

danwetherald commented 9 years ago

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?

daltoniam commented 9 years ago

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:

That basic model should make the images show up properly.

daltoniam commented 9 years ago

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
})
daltoniam commented 9 years ago

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.

anthonycastelli commented 9 years ago

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!

daltoniam commented 9 years ago

:+1: Shocked it took me this long to notice :smile:. Just trying to be proactive!

daltoniam commented 9 years ago

@dan003400 did you try the latest code? Did it seem to fix the issue?

daltoniam commented 9 years ago

I am going to assume this one is fixed. We can reopen the issue if it comes up again.