Avid developer who has a passion for | 

Learn more about myself and what makes me so passionate about various forms of software development.

Shimmer Effect for Xamarin.iOS

Posted On 2020-10-08

Recently I decided to swap out the old standby of a spinner for a shimmer effect on an app I'm working on at work and today I'm going to go through a simple way to achieve this effect.

First off, why use a shimmer effect? the spinner has been the standard way to inform the user about a loading screen but in some cases the spinner could be a turn-off and if you add an overlay as well it's now blocking the UI. A shimmer will let the user know what to expect once the app has fully loaded.

When you think shimmer, most people think Facebook, and they do offer a nice library but this article will not be on that library as I found a simpler way to do this and because the library itself looks abandoned in a way.

Shimmer Example

I found a really nice swift article article that I ported over to C# and being the nice guy that I am, I'm going to post that here.

public enum ShimmerDirection
{
    TopToBottom,
    BottomToTop,
    LeftToRight,
    RightToLeft
}

public static class ShimmerHelper
{
    public static void StartShimmeringAnimation(this UIView view, ShimmerDirection direction = ShimmerDirection.LeftToRight)
    {
        var lightColor = new UIColor(1.0f, 1.0f, 1.0f, 0.1f).CGColor;
        var blackColor = UIColor.Black.CGColor;
        var gradient = new CAGradientLayer
        {
            Colors = new CGColor[] { blackColor, lightColor, blackColor },
            Frame = new CGRect(-view.Bounds.Size.Width, -view.Bounds.Size.Height, 3 * view.Bounds.Size.Width, 3 * view.Bounds.Size.Height)
        };

        switch (direction)
        {
            case ShimmerDirection.TopToBottom:
                gradient.StartPoint = new CGPoint(0.5f, 0.0f);
                gradient.EndPoint = new CGPoint(0.5f, 1.0f);
                break;
            case ShimmerDirection.BottomToTop:
                gradient.StartPoint = new CGPoint(0.5f, 1.0f);
                gradient.EndPoint = new CGPoint(0.5f, 0.0f);
                break;
            case ShimmerDirection.LeftToRight:
                gradient.StartPoint = new CGPoint(0.0f, 0.5f);
                gradient.EndPoint = new CGPoint(1.0f, 0.5f);
                break;
            case ShimmerDirection.RightToLeft:
                gradient.StartPoint = new CGPoint(1.0f, 0.5f);
                gradient.EndPoint = new CGPoint(0.0f, 0.5f);
                break;
        }

        gradient.Locations = new NSNumber[] { 0.35, 0.50, 0.65 };

        view.Layer.Mask = gradient;

        var animation = CABasicAnimation.FromKeyPath("locations");

        animation.From = NSArray.FromObjects(new NSNumber[] { 0.0, 0.1, 0.2 });
        animation.To = NSArray.FromObjects(new NSNumber[] { 0.8, 0.9, 1.0 });
        animation.Duration = 2.0f;
        animation.RepeatCount = 1000;

        gradient.AddAnimation(animation, "shimmerAnimation");
    }

    public static void StopShimmeringAnimation(this UIView view)
    {
        view.Layer.Mask = null;
    }

The usage is simple, for the view you wish to shimmer you do the following:

lblHeader.StartShimmeringAnimation();

Of course to turn it off you do the following:

lblHeader.StopShimmeringAnimation();

You can see the full code with example here.