You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化CAGradientLayer闪烁动画:消除白色闪光后的灰色区域

解决TableView Cell Shimmer动画后残留灰色块的问题

你的问题出在动画参数冲突、渐变位置过渡不连贯,以及渐变层覆盖范围可能未正确设置这几点上,以下是修正方案:

关键问题分析

  • 单个动画同时设置了repeatCount = .infinity和repeatCount = 1,且动画组时长与单个动画时长不匹配,导致动画衔接断层
  • 初始渐变位置和动画目标位置的取值不合理,闪光过后渐变无法平滑回归,出现纯色灰色区域
  • 可能未设置gradientLayer.frame,导致渐变层未完全覆盖目标区域

修正后的代码

func startShimmerAnimation() {
    // 核心:确保渐变层完全覆盖需要闪烁的区域,比如cell的bounds
    gradientLayer.frame = self.bounds
    
    gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
    gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)

    gradientLayer.colors = [
        UIColor.systemGray5.cgColor,
        UIColor.white.cgColor,
        UIColor.systemGray5.cgColor
    ]

    // 初始位置靠左,让动画起始自然无突兀
    gradientLayer.locations = [0.0, 0.1, 0.2]
    gradientLayer.cornerRadius = 10
    
    let animation = CABasicAnimation(keyPath: "locations")
    // 动画从初始位置过渡到右侧边缘,全程保持渐变覆盖视图
    animation.fromValue = [0.0, 0.1, 0.2]
    animation.toValue = [0.8, 0.9, 1.0]
    animation.duration = 1.5
    animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
    
    let group = CAAnimationGroup()
    group.animations = [animation]
    group.duration = 1.5
    group.repeatCount = .infinity
    
    // 若需要闪光来回移动,可开启自动反转,此时调整from/toValue为[-0.2, -0.1, 0.0]和[1.0, 1.1, 1.2]
    // group.autoreverses = true
    
    gradientLayer.add(group, forKey: "shimmer")
}

关键修改说明

  • 强制设置渐变层Frame:必须让gradientLayer.frame匹配目标视图的边界,避免局部区域显示纯色背景
  • 优化Locations参数:让渐变始终在视图范围内过渡,动画结束时刚好抵达右侧边缘,无缝衔接下一次循环
  • 统一动画参数:移除单个动画的重复次数、fillMode等冗余设置,由动画组统一控制逻辑,避免参数冲突
  • 可选自动反转:如果需要闪光来回滑动,开启autoreverses = true并调整位置参数,实现更自然的往复动画

内容的提问来源于stack exchange,提问作者artexhibit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 21:08:24