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

如何用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()

错误原因

  1. 你添加的三个动画是同时执行的,并非按顺序触发,alpha属性的0和1赋值会直接冲突,无法形成过渡效果
  2. 直接修改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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 22:04:53