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

iOS15真机UIProgressView progressTintColor动画渐变异常如何解决?

问题触发原因
  • iOS 15对UIProgressView的.bar样式底层渲染逻辑做了不兼容更新:该样式默认会关联栏类组件的毛玻璃特效,同时系统会为已填充的进度区域自动添加内置渐变层,你设置的纯白色progressTintColor会被渐变层和毛玻璃效果覆盖,最终呈现灰到白的渐变效果。
  • 当前动画实现方式不符合系统规范:progress属性本身支持自带动画过渡,你直接修改progress为1后调用layoutIfNeeded的写法,在iOS15+会同时触发进度位移、颜色变更的双重隐式动画,进一步放大了系统自带的渐变效果,导致动画初始阶段完全显示为灰色。
适配解决方案

方案1:替换进度条样式(改动最小,适配最快)

直接将.bar样式替换为.default样式,.default样式在全iOS版本都不会自带渐变、毛玻璃特效,原有颜色、圆角配置可以直接生效:

// 仅修改初始化时的样式参数即可
let segment = UIProgressView(progressViewStyle: .default)
segment.layer.cornerRadius = 3.0
segment.layer.masksToBounds = true
// 其余原有配置保持不变

如果要做版本适配,仅给iOS15及以上版本替换样式:

let segment: UIProgressView
if #available(iOS 15, *) {
    segment = UIProgressView(progressViewStyle: .default)
} else {
    segment = UIProgressView(progressViewStyle: .bar)
}

方案2:保留.bar样式,移除系统自带渐变层

如果必须保留.bar样式,可以在初始化时遍历子view移除系统自动添加的渐变层,强制覆盖填充色:

if #available(iOS 15, *) {
    segment.subviews.forEach { barSubview in
        // 移除系统自带的渐变层
        barSubview.layer.sublayers?.forEach { layer in
            if layer.isKind(of: CAGradientLayer.self) {
                layer.removeFromSuperlayer()
            }
        }
        // 强制设置填充色为纯白
        barSubview.backgroundColor = Colors.white
    }
}

同时修改动画实现为系统推荐的setProgress写法,避免隐式动画冲突:

// 替换原有动画代码
UIView.animate(withDuration: storyTime, delay: 0, options: .curveLinear) {
    self.progressBar.setProgress(1.0, animated: true)
} completion: { [weak self] _ in
    guard let self = self else { return }
    // 原有动画完成逻辑
}

方案3:自定义进度条(彻底解决版本差异)

如果要完全对齐多系统版本的视觉效果,直接用两个UIView实现极简进度条,修改填充视图的宽度约束做动画,完全不受系统API更新影响:

// 自定义进度条示例
let trackView = UIView()
trackView.backgroundColor = UIColor.black.withAlphaComponent(0.2)
trackView.layer.cornerRadius = 3
trackView.layer.masksToBounds = true

let progressView = UIView()
progressView.backgroundColor = Colors.white
trackView.addSubview(progressView)

// 布局时保留进度条宽度约束的引用
var progressWidthConstraint: NSLayoutConstraint!
progressWidthConstraint = progressView.widthAnchor.constraint(equalToConstant: 0)
// 其余约束:progressView左、上、下等于trackView,高度等于trackView高度

// 动画时直接修改宽度约束
progressWidthConstraint.constant = trackView.bounds.width
UIView.animate(withDuration: storyTime, delay: 0, options: .curveLinear) {
    self.view.layoutIfNeeded()
} completion: { _ in
    // 动画完成逻辑
}

内容的提问来源于stack exchange,提问作者Emre Önder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 07:24:07