优化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
相关产品推荐
相关产品推荐

