iOS15中UIProgressView调用setProgress带动画时变透明如何解决
iOS15 UIProgressView 带动画设置进度时透明问题解决方案
问题原因
iOS15 对 UIProgressView 的默认动画逻辑做了改动,调用带animated: true参数的进度设置方法时,系统会默认在进度动画中叠加透明度渐变效果,该效果属于内置layer层动画,直接设置view的alpha属性无法覆盖。
可行解决方案
方案1:自定义动画替换系统默认动画
放弃使用系统自带的animated参数,手动通过UIView动画控制进度变化,避免系统插入透明度动画:
UIView.performWithoutAnimation { // 先强制重置透明度,禁用隐式动画 self.progress.alpha = 1 self.progress.layoutIfNeeded() } // 手动执行和系统默认时长一致的进度动画 UIView.animate(withDuration: 0.25) { self.progress.setProgress(1.0, animated: false) self.progress.layoutIfNeeded() }
方案2:子类化UIProgressView统一适配
如果项目中多处用到进度条,可以统一重写setProgress方法处理iOS15的适配,后续直接使用自定义子类即可:
class FixedProgressView: UIProgressView { override func setProgress(_ progress: Float, animated: Bool) { guard #available(iOS 15, *), animated else { super.setProgress(progress, animated: animated) return } // 移除系统自动添加的透明度动画 layer.removeAllAnimations() UIView.animate(withDuration: 0.25) { super.setProgress(progress, animated: false) } } }
方案3:自定义进度/轨道图片
直接给进度条设置自定义的纯色图片,绕过系统默认样式的动画逻辑:
// 先实现纯色生成UIImage的扩展 extension UIImage { convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) { UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale) color.setFill() UIRectFill(CGRect(origin: .zero, size: size)) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() guard let cgImage = image?.cgImage else { return nil } self.init(cgImage: cgImage) } } // 给进度条设置自定义图片 progress.trackImage = UIImage(color: .lightGray, size: CGSize(width: 1, height: 4)) progress.progressImage = UIImage(color: .systemBlue, size: CGSize(width: 1, height: 4))
内容的提问来源于stack exchange,提问作者Dan Kamilov
相关产品推荐
相关产品推荐

