Since Xamarin Forms Listview now reuses cells in iOS (as it should) one small piece was overlooked. The reused cells now displays previously displayed images for a short while until the new image is downloaded.
This behavior is mitigated by a cache, so once an image is loaded it's set instantly the next time the cell is displayed.
I've also filed a bug with a sample project available at https://bugzilla.xamarin.com/show_bug.cgi?id=28628 and the sample project to visualize the issue at here.
There are a number of ways around this.
Suggestion one - half-way around
This solution works, but images are blank and then suddenly pops into place. It's visually ugly, but better than the original version of the ImageRenderer. What is does is that it sets the Image to null (the UIImage.Image) when IsLoading changes from False to True. The problem is that is does this even when the image isn't loading from the internet, but from the cache as well, leaving us with no option to initiate a fade in.
assembly: ExportRenderer (typeof (Image), typeof (CustomImageRenderer))]
namespace ImageListView.iOS.Renderers
{
public class CustomImageRenderer : ImageRenderer
{
public CustomImageRenderer()
{
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if ((sender as Image).IsLoading)
{
// The image will be reset in base if there is one already in the cache.
// If it isn't already loaded we don't want to display the previous image
// This is however called each time a cell comes into view so it can't
// be used for opacity fading or likewise...
// This should be handled by the code in the ImageRenderer
Control.Image = null;
}
base.OnElementPropertyChanged(sender, e);
}
}
}
namespace ImageListView.iOS.Renderers
{
public class CustomImageRenderer : ImageRenderer
{
public CustomImageRenderer()
{
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if ((sender as Image).IsLoading)
{
// The image will be reset in base if there is one already in the cache.
// If it isn't already loaded we don't want to display the previous image
// This is however called each time a cell comes into view so it can't
// be used for opacity fading or likewise...
// This should be handled by the code in the ImageRenderer
Control.Image = null;
}
base.OnElementPropertyChanged(sender, e);
}
}
}
Suggestion two - wrap it
Wrap your image in a custom control and handle all the loading and caching yourself.Suggestion three - rewrite it
Write your own Image-renderer from scratch to take into account when an image is fetched from the cache or not to enable a nice fade in. This is what I hope will come out of the bug report.Suggestion four - hijack the cache
The next article is going to be about this. But simply put, we highjack the cache and control the image flow from that way. Stay tuned! :D
Summary
I would go with suggestion one for now and wait for the outcome of the bug report.
Have a great one!
No comments:
Post a Comment