微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 UIViewPropertyAnimator 动画 UILabel textColor 属性

如何解决使用 UIViewPropertyAnimator 动画 UILabel textColor 属性

我有一个看似简单的问题,但我还没有找到解决方案。

我使用 UIViewPropertyAnimator 和滑块手动调整动画师的 fractionComplete 属性为内部带有标签的视图设置动画。

在我动画的视图中,我有一个 UILabel,我想动画它的 textColor

我发现 SO answers 建议像这样为 textColor 设置动画:

UIView.transition(with: yourLabel,duration: 0.3,options: .transitionCrossdissolve,animations: {
  self.yourLabel.textColor = .red
},completion: nil)

但是,对我来说这不起作用,因为我希望动画根据我为动画师设置的 fractionComplete 进行。

解决方法

正如评论中所说,textColor 属性不能被动画化。 但是,有一种称为颜色插值的技术,这可能是一个不错的解决方法。

您可以在 this thread 中找到多种方法来解决此问题,但是,我也为您提供了一种解决方案:

extension UIColor {
var components: (r: CGFloat,g: CGFloat,b: CGFloat,a: CGFloat) {
    let components = self.cgColor.components!

    switch components.count == 2 {
    case true : 
        return (r: components[0],g: components[0],b: components[0],a: components[1])
    case false: 
        return (r: components[0],g: components[1],b: components[2],a: components[3])
    }
}

static func interpolate(from fromColor: UIColor,to toColor: UIColor,with progress: CGFloat) -> UIColor {
    let fromComponents = fromColor.components
    let toComponents = toColor.components
    
    let r = (1 - progress) * fromComponents.r + progress * toComponents.r
    let g = (1 - progress) * fromComponents.g + progress * toComponents.g
    let b = (1 - progress) * fromComponents.b + progress * toComponents.b
    let a = (1 - progress) * fromComponents.a + progress * toComponents.a
    
    return UIColor(red: r,green: g,blue: b,alpha: a)
}
}

然后,您所要做的就是在滑块值更改时调用的函数中执行此操作:

@objc func sliderChanged(_ sender: UISlider) {
     animator.fractionComplete = CGFloat(sender.value)
     yourLabel.textColor = UIColor.interpolate(from: fromColor,to: toColor,with: sender.value)
}

您不是在为 textColor 设置动画,而是在每次调用 sliderChanged 时将其更改为不同的颜色,但是这种变化是渐进的,并且不会从您的起始颜色跳到您的第二个颜色,所以我认为它应该达到你想要的结果。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。