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

如何延迟调用displayFinalOutcome以等待UIImage动画完成?

解决UIImage动画未完成就触发后续方法的问题

嘿,这个问题我之前做骰子类应用时也碰到过!用UIImage.animatedImage实现的动画,系统默认不会提供动画完成的回调钩子,所以得手动处理延迟逻辑来保证displayFinalOutcome()在动画结束后再执行。下面给你两种靠谱的解决思路:

方法一:根据动画总时长精准延迟调用

UIImage.animatedImage的duration参数就是整个动画循环一次的总时长,我们可以直接用这个时长设置延迟,确保动画结束后再展示结果。

代码示例

@IBAction func rollButtonPressed(_ sender: UIButton) {
    // 先禁用按钮防止重复触发
    sender.isEnabled = false
    animateImages(with: sender)
}

func animateImages(with sender: UIButton) {
    // 替换成你自己的动画图片集合
    let diceImages = [
        UIImage(named: "dice1"),
        UIImage(named: "dice2"),
        UIImage(named: "dice3"),
        UIImage(named: "dice4"),
        UIImage(named: "dice5"),
        UIImage(named: "dice6")
    ].compactMap { $0 }
    
    // 每张图片的显示时长,按需调整
    let perFrameDuration = 0.1
    let totalAnimationDuration = TimeInterval(diceImages.count) * perFrameDuration
    
    // 给ImageView设置动画图片
    diceImageView.image = UIImage.animatedImage(with: diceImages, duration: totalAnimationDuration)
    
    // 延迟到动画结束后执行结果展示
    DispatchQueue.main.asyncAfter(deadline: .now() + totalAnimationDuration) { [weak self, weak sender] in
        self?.displayFinalOutcome()
        // 动画结束后重新启用按钮
        sender?.isEnabled = true
    }
}

注意细节

  • 如果你的动画需要重复多次(比如设置了diceImageView.animationRepeatCount = 2),延迟时间要乘以重复次数:totalAnimationDuration * 2
  • 用[weak self, weak sender]避免循环引用,防止内存泄漏

方法二:监听ImageView动画结束通知(更灵活)

如果动画逻辑复杂、时长动态变化,不想手动计算时长,可以监听UIImageView的动画结束通知:

代码示例

@IBAction func rollButtonPressed(_ sender: UIButton) {
    sender.isEnabled = false
    // 添加动画结束通知监听
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(animationDidFinish),
        name: NSNotification.Name.UIImageViewAnimationDidStop,
        object: diceImageView
    )
    animateImages()
}

func animateImages() {
    let diceImages = [/* 你的图片数组 */].compactMap { $0 }
    diceImageView.image = UIImage.animatedImage(with: diceImages, duration: 0.6)
    // 手动启动动画(部分场景下需要)
    diceImageView.startAnimating()
}

@objc func animationDidFinish() {
    // 移除通知监听,避免重复触发
    NotificationCenter.default.removeObserver(
        self,
        name: NSNotification.Name.UIImageViewAnimationDidStop,
        object: diceImageView
    )
    displayFinalOutcome()
    // 重新启用按钮(可通过tag或属性引用按钮)
    if let rollButton = view.viewWithTag(100) as? UIButton { // 假设按钮tag设为100
        rollButton.isEnabled = true
    }
}

这种方法完全由系统通知动画结束时机,不用手动计算时长,适合动态调整的动画场景。


内容的提问来源于stack exchange,提问作者Matthew Guo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:11:24