UI 使用 animateKeyframes 的动画对按钮标题颜色没有任何影响

UI Animation using animateKeyframes does nothing to Button Title Color

我正在尝试使用 animateKeyframes 为我的 UIButton Title Color 设置动画颜色但它除了加载动画中的最后一个状态外什么都不做,在本例中为 purpleText。我使用相同的代码来设置按钮颜色和 UIView 背景颜色的动画,没有任何问题。

我还在 Interface Builder 中将按钮更改为 自定义按钮 ,但这也无济于事。

        UIView.animateKeyframes(withDuration: 12, delay: 12, options: [.allowUserInteraction, .repeat, .autoreverse], animations: {
            UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.25, animations: {
                self.infoButton.setTitleColor(blueText, for: UIControlState.normal)
            })
            UIView.addKeyframe(withRelativeStartTime: 0.2, relativeDuration: 0.25, animations: {
                self.infoButton.setTitleColor(greenText, for: UIControlState.normal)
            })
            UIView.addKeyframe(withRelativeStartTime: 0.4, relativeDuration: 0.25, animations: {
                self.infoButton.setTitleColor(yellowText, for: UIControlState.normal)
            })
            UIView.addKeyframe(withRelativeStartTime: 0.6, relativeDuration: 0.25, animations: {
                self.infoButton.setTitleColor(redText, for: UIControlState.normal)
            })
            UIView.addKeyframe(withRelativeStartTime: 0.8, relativeDuration: 0.25, animations: {
                self.infoButton.setTitleColor(purpleText, for: UIControlState.normal)
            })
        }, completion: nil)

在动画块中调用 setTitleColor() 不起作用,因为 UIView.animate 仅适用于动画属性,例如 infoButton.backgroundColor.

不幸的是,按钮属性像 tintColor aren't animatable。您也不应该直接访问按钮的 titleLabel,系统按钮是 nil

相反,您可以使用 UIView.transitionsetTitleColor()。然后你可以把它放在一个Timer...我通常不喜欢用定时器做动画,但我想不出任何其他方法。

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    
    let colors: [UIColor] = [.blue, .green, .yellow, .red, .purple]
    var currentIndex = 0
    
    _ = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { timer in
        if colors.indices.contains(currentIndex) {
            UIView.transition(with: self.infoButton, duration: 0.5, options: [.transitionCrossDissolve, .allowUserInteraction]) {
                self.infoButton.setTitleColor(colors[currentIndex], for: .normal)
            }
            currentIndex += 1
        } else {
            currentIndex = 0
        }
    }
}

结果: