I have the smooth scrolling issue at my UITableView with UITableViewCell which contains UIImageView. Similar issues could be found all over the StrackOverflow but none of the proposed solutions helped me to completely get rid of the lag.
My case is quite common:
- images are stored at application storage (in my sample at app bundle)
- images could have different size (500x500, 1000x1000, 1500x1500)
- I need to display those images in UITableView where UIImageView size is 120x120 (retina)
I have followed multiple optimization tips and managed to optimize scrolling a lot. Unfortunately it is still not perfect. This is my scenario:
- first I moved all the image loading/processing/resizing logic to the background thread
- UITableViewCell reuse is enabled
- once UITableViewCell is in view I clear old values (settings to null) and start background thread to load the image
- at this point we are in background thread and I'm adding 500 ms delay to avoid settings new image to often (in case we are scrolling fast) (see below explanation)
- if UIImage exists at static image cache (regular dictionary with UIImage instances) - fetch that one and go to the step 9.
- if not - load new image from bundle (imageWithName) using url to app bundle (in real world scenario images will be stored to application storage, not bundle)
- once image is loaded resize it to 120x120 using graphics context
- save resized image to the static image cache
- at this point we have instance to UIImage and process is in the background thread. From here we move back to UI Thread with the given image
- if data context was cleared (for example UITableViewCell disappeared or was reused to display another image) we skip processing of the currently available image.
- if data context is the same - assign UIImage to UIImageView with an alpha animation (UIView.Animate)
- once UITableViewCell is out of view - clear the data context
Originally before starting new background thread to fetch the image here (step 1) was UIImage cache check without background thread. In this case if we have the image in the cache we assign it instantly and this introduces a great lag during fast scrolling (we assign images to often as long as we fetch them instantly). Those lines are commented at my example attached below.
There are still two issues:
- at some point during scrolling I still have a small lag (at the moment when I'm assign new UIImage to UIImageView.
- (this one is more noticeable) when you tap on item and go back from details there is a lag right before back navigation animation is finished.
Any suggest how to deal with those two issues or how to optimize my scenario are appreciated
Please take into account that sample written in Xamarin but I don't believe that Xamarin is the cause of the problem as long as I have the same issue for the app written in ObjectiveC as well.