如何用UIViewPropertyAnimator实现ImageView的交叉淡入淡出效果?
使用UIViewPropertyAnimator实现UIImageView交叉溶解动画
问题背景
你已通过UIView.transition实现UIImageView的交叉溶解效果:
UIView.transition( with: imageView, duration: 2, options: .transitionCrossDissolve, animations: { [weak self] in self?.imageView.image = anImage }, completion: { // do something } )
但尝试以下UIViewPropertyAnimator代码未达到预期效果:
let animator = UIViewPropertyAnimator(duration: 2, curve: .linear) animator.addAnimations { self.imageView.alpha = 0 } animator.addAnimations { self.imageView.image = image } animator.addAnimations { self.imageView.alpha = 1 } animator.startAnimation()
错误原因
- 你添加的三个动画是同时执行的,并非按顺序触发,alpha属性的0和1赋值会直接冲突,无法形成过渡效果
- 直接修改
imageView.image不属于UIKit支持的可动画属性变化,无法通过常规属性动画实现平滑过渡
正确实现方案
方案一:用UIViewPropertyAnimator包裹系统transition动画
这种方式复用系统的交叉溶解逻辑,同时保留UIViewPropertyAnimator的进度控制、暂停/继续能力:
let newImage = UIImage(named: "your-new-image")! let animator = UIViewPropertyAnimator(duration: 2, curve: .linear) { UIView.transition(with: self.imageView, duration: animator.duration, options: .transitionCrossDissolve, animations: { [weak self] in self?.imageView.image = newImage }, completion: nil) } // 可按需控制动画: // animator.pauseAnimation() // 暂停动画 // animator.fractionComplete = 0.5 // 跳转到50%进度 // animator.continueAnimation(withTimingParameters: nil, durationFactor: 1) // 继续动画 animator.startAnimation()
方案二:双ImageView手动实现交叉溶解
通过叠加两个UIImageView,分别控制alpha实现过渡,灵活性更高:
let newImage = UIImage(named: "your-new-image")! // 创建覆盖在原ImageView上的新视图 let overlayImageView = UIImageView(frame: self.imageView.bounds) overlayImageView.contentMode = self.imageView.contentMode overlayImageView.image = newImage overlayImageView.alpha = 0 self.imageView.addSubview(overlayImageView) let animator = UIViewPropertyAnimator(duration: 2, curve: .linear) { // 原图片渐隐,新图片渐显 self.imageView.alpha = 0 overlayImageView.alpha = 1 } // 动画完成后清理视图 animator.addCompletion { [weak self] _ in guard let self = self else { return } self.imageView.image = newImage self.imageView.alpha = 1 overlayImageView.removeFromSuperview() } animator.startAnimation()
内容的提问来源于stack exchange,提问作者isenwald2022
相关产品推荐
相关产品推荐

