如何延迟调用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
相关产品推荐
相关产品推荐

