Mobile Development 16 min read

Sweep Light Loading Effects: Principles and Cross‑Platform Implementation

Sweep‑light loading effects, such as skeleton‑screen and logo sweeps, improve perceived performance by overlaying a moving translucent gradient mask, and can be implemented on iOS using Core Animation layers and timers, while Android uses shape drawables, ObjectAnimator or Canvas PorterDuff blending, with theme and performance considerations.

Baidu Geek Talk
Baidu Geek Talk
Baidu Geek Talk
Sweep Light Loading Effects: Principles and Cross‑Platform Implementation

With the rapid development of mobile internet, many creative interactive experiences have emerged. Sweep light loading effects, such as skeleton‑screen sweep and logo sweep, are common loading animations that provide a better visual experience than traditional spinners.

The article explains the principles of these effects and provides detailed iOS and Android implementations, including differences between the two platforms.

Skeleton‑Screen Sweep Light

Skeleton screen is a placeholder shown while data loads. The sweep effect can be achieved by overlaying a translucent gradient mask on the skeleton view and moving it horizontally.

// Create mask view
_lightCover = [[UIImageView alloc] initWithFrame:self.bounds];
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = _lightCover.bounds;
gradientLayer.colors = @[(id)[UIColorFromRGBA(0xFFFFFF,0) CGColor],
                         (id)[UIColorFromRGBA(0xFFFFFF,0.3) CGColor],
                         (id)[UIColorFromRGBA(0xFFFFFF,0.5) CGColor],
                         (id)[UIColorFromRGBA(0xFFFFFF,0.3) CGColor],
                         (id)[UIColorFromRGBA(0xFFFFFF,0) CGColor]];
gradientLayer.startPoint = CGPointMake(0,0.5f);
gradientLayer.endPoint   = CGPointMake(1,0.5f);
[_lightCover.layer insertSublayer:gradientLayer atIndex:0];
_lightCover.transform = CGAffineTransformMakeTranslation(-self.bounds.size.width,0);

The mask is animated with a timer or UIView animation to translate from left to right.

self.lightSweepTimer = [NSTimer scheduledTimerWithTimeInterval:intervalTime target:self selector:@selector(lightSweepAnimation) userInfo:nil repeats:YES];
[UIView animateWithDuration:duration animations:^{
    self.lightCover.transform = CGAffineTransformMakeTranslation(self.bounds.size.width,0);
}];

Logo (Bear‑Paw) Sweep Light

Logo sweep light requires a three‑layer structure: the background image, a moving gradient layer, and a mask that cuts out the logo shape.

// Gradient layer for iOS
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.colors = @[(id)[UIColor colorWithWhite:1 alpha:0].CGColor,
                         (id)[UIColor colorWithWhite:1 alpha:0.9].CGColor,
                         (id)[UIColor colorWithWhite:1 alpha:0.9].CGColor,
                         (id)[UIColor colorWithWhite:1 alpha:0].CGColor];
gradientLayer.startPoint = CGPointMake(0,0.5);
gradientLayer.endPoint   = CGPointMake(1,0.35);
[self.loadingImgView.layer addSublayer:gradientLayer];

// Mask layer
CALayer *maskLayer = [[CALayer alloc] init];
maskLayer.contents = (id)[self lightImg].CGImage;
self.loadingImgView.layer.mask = maskLayer;

Animation is performed with CABasicAnimation on the gradient layer’s transform.

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];
animation.duration = 2;
animation.repeatCount = HUGE_VALF;
animation.fromValue = @(-loadingWidth);
animation.toValue   = @(loadingWidth);
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[self.gradientLayer addAnimation:animation forKey:@"loading_animation_key"];

Android Implementation

Android uses a <shape> XML to define a horizontal gradient and ObjectAnimator to move it, or a Canvas‑based approach with PorterDuffXfermode for more complex blending.

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <gradient android:startColor="#00ffffff"
              android:centerColor="#7fffffff"
              android:endColor="#00ffffff"/>
</shape>
ObjectAnimator translationX = ObjectAnimator.ofFloat(mMoveLight, "translationX", -displayWidth, displayWidth);
translationX.setDuration(duration);
translationX.start();

When a three‑layer composition is needed, a PorterDuffXfermode with DST_IN is applied on a Canvas to combine the source bitmap (gradient) and the destination bitmap (logo).

Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawBitmap(srcBitmap, 0, 0, paint);
canvas.drawBitmap(dstBitmap, 0, 0, null);

The article also discusses theme‑related issues (day, night, dark modes) and provides performance tips such as avoiding extra image assets.

In summary, sweep‑light loading effects are implemented by overlaying a moving translucent mask on the target view. iOS leverages Core Animation and CALayer, while Android can use Shape drawables, ObjectAnimator, or low‑level Canvas drawing with PorterDuff modes.

iOSAndroidcanvasUI DevelopmentCoreAnimationLoading AnimationSweep Light
Baidu Geek Talk
Written by

Baidu Geek Talk

Follow us to discover more Baidu tech insights.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.