swift实现颜色渐变以及转换动画

本文是通过结合使用CAGradientLayer、CABasicAnimation以及CAAnimationDelegate来达到颜色渐变以及转换的动画,下面是今天要达成的效果图:

首先创建一个CAGradientLayer和几个自己喜欢的颜色,让VC持有。

let colorOne = #colorLiteral(red: 0.2392156869, green: 0.6745098233, blue: 0.9686274529, alpha: 1).cgColor
let colorTwo = #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1).cgColor
let colorThree = #colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1).cgColor
let gradient = CAGradientLayer()

接下来为gradient赋值,将其frame等同于视图的大小,然后颜色先设置为colorOne和colorTwo,起始点和结束点分别为CGPoint(x:0, y:0)和CGPoint(x:1, y:1),并设置让其在后台线程异步绘制,最后添加到view的layer的sublayer中。

gradient.frame = self.view.bounds
gradient.colors = [colorOne,colorTwo]
gradient.startPoint = CGPoint(x:0, y:0)
gradient.endPoint = CGPoint(x:1, y:1)
gradient.drawsAsynchronously = true
self.view.layer.insertSublayer(gradient, at: 0)

现在运行后会得到下面的结果:

颜色渐变是做到了,那么如何做到颜色渐变的转换呢?这里还是需要用到CABasicAnimation.
在gradient创建完之后,添加并调用一个方法animateGradient,在里面添加一个keyPath为colors的CABasicAnimation,设置动画时长为3s,设置结束值等一系列属性。

func animateGradient() {
  let gradientChangeAnimation = CABasicAnimation(keyPath: "colors")
        gradientChangeAnimation.duration = 3.0
        gradientChangeAnimation.toValue =  [colorTwo,colorThree]
        gradientChangeAnimation.fillMode = CAMediaTimingFillMode.forwards
        gradientChangeAnimation.isRemovedOnCompletion = false
        gradient.add(gradientChangeAnimation, forKey: "gradientChangeAnimation")
      }

这里就完成了转换动画。但是这里有个问题就是这里只转换了一次,无法转换多次颜色。那么这里就需要设置好toValue,让每次的toValue都不一样。
创建一个currentGradient和gradientSet让VC持有。

var currentGradient: Int = 0
var gradientSet = [[CGColor]]()

在animateGradient中每次调用的时候,都对currentGradient的值进行判断和处理。

if currentGradient < gradientSet.count - 1 {
            currentGradient += 1
        } else {
            currentGradient = 0
        }

并修改gradientChangeAnimation的toValue:

let gradientChangeAnimation = CABasicAnimation(keyPath: "colors")
gradientChangeAnimation.duration = 3.0
gradientChangeAnimation.toValue = gradientSet[currentGradient]
gradientChangeAnimation.fillMode = CAMediaTimingFillMode.forwards
gradientChangeAnimation.isRemovedOnCompletion = false
gradientChangeAnimation.repeatCount = Float.infinity
gradient.add(gradientChangeAnimation, forKey: "gradientChangeAnimation")

这里运行后发现还是不行,还是只有一种颜色的转换,这是因为这里只调用了一次animateGradient()。那么如何在合适的时机,也就是动画结束的时候再调用一次animateGradient呢?这里就需要用到CAAnimationDelegate。
在CAAnimationDelegate的animationDidStop方法中重新调用animateGradient。注意这里的gradient.colors 也要改变,否则就会一直是[colorOne, colorTwo]到其他颜色的变换。

func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
        
        // if our gradient animation ended animating, restart the animation by changing the color set
        if flag {
            gradient.colors = gradientSet[currentGradient]
            animateGradient()
        }
    }

完整代码:

import UIKit

class ViewController: UIViewController, CAAnimationDelegate {
    let colorOne = #colorLiteral(red: 0.2392156869, green: 0.6745098233, blue: 0.9686274529, alpha: 1).cgColor
    let colorTwo = #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1).cgColor
    let colorThree = #colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1).cgColor
    let gradient = CAGradientLayer()
    
    var currentGradient: Int = 0
    var gradientSet = [[CGColor]]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        NotificationCenter.default.addObserver(self, selector: #selector(handleEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
        
    }
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        createGradientView()
    }
    
    @objc private func handleEnterForeground() {
        animateGradient()
    }
    
    func animateGradient() {
        // cycle through all the colors, feel free to add more to the set
        if currentGradient < gradientSet.count - 1 {
            currentGradient += 1
        } else {
            currentGradient = 0
        }
        
        // animate over 3 seconds
        let gradientChangeAnimation = CABasicAnimation(keyPath: "colors")
        gradientChangeAnimation.duration = 3.0
        gradientChangeAnimation.toValue = gradientSet[currentGradient]
        gradientChangeAnimation.fillMode = CAMediaTimingFillMode.forwards
        gradientChangeAnimation.isRemovedOnCompletion = false
        //gradientChangeAnimation.repeatCount = Float.infinity
        gradientChangeAnimation.delegate = self
        gradient.add(gradientChangeAnimation, forKey: "gradientChangeAnimation")
    }
    
    func createGradientView() {
        
        // overlap the colors and make it 3 sets of colors
        gradientSet.append([colorOne, colorTwo])
        gradientSet.append([colorTwo, colorThree])
        gradientSet.append([colorThree, colorOne])
        
        // set the gradient size to be the entire screen
        gradient.frame = self.view.bounds
        gradient.colors = gradientSet[currentGradient]
        gradient.startPoint = CGPoint(x:0, y:0)
        gradient.endPoint = CGPoint(x:1, y:1)
        gradient.drawsAsynchronously = true
        
        self.view.layer.insertSublayer(gradient, at: 0)
        
        animateGradient()
    }
    func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
        
        // if our gradient animation ended animating, restart the animation by changing the color set
        if flag {
            gradient.colors = gradientSet[currentGradient]
            animateGradient()
        }
    }
    
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • SwiftUI使用Paths和AnimatableData实现酷炫的颜色切换动画

    老铁们,是时候燥起来了!本文中我们将学习如何使用 SwiftUI 中的 Paths 和 AnimatableData 来制作颜色切换动画. 这些快速切换的动画是怎么实现的呢?让我们来看下文吧! 基础 要实现动画的关键是在 SwiftUI 中创建一个实现 Shape 协议的结构体.我们把它命名为 SplashShape .在 Shape 协议中,有一个方法叫做 path(in rect: CGRect) -> Path ,这个方法可以用来设置图形的外观.我们就用这个方法来实现本文中的各种动画. 创

  • iOS SwiftUI 颜色渐变填充效果的实现

    SwiftUI 为我们提供了各种梯度选项,所有这些选项都可以通过多种方式使用. Gradient 渐变器 A color gradient represented as an array of color stops, each having a parametric location value. gradient是一组颜色的合集,每个颜色都忽略位置参数 LinearGradient 线性渐变器 线性渐变器拥有沿轴进行渐变函数,我们可以自定义设置颜色空间.起点和终点. 下面我们看看Linear

  • swift实现颜色渐变以及转换动画

    本文是通过结合使用CAGradientLayer.CABasicAnimation以及CAAnimationDelegate来达到颜色渐变以及转换的动画,下面是今天要达成的效果图: 首先创建一个CAGradientLayer和几个自己喜欢的颜色,让VC持有. let colorOne = #colorLiteral(red: 0.2392156869, green: 0.6745098233, blue: 0.9686274529, alpha: 1).cgColor let colorTwo

  • IOS绘制动画颜色渐变折线条

    先给大家展示下效果图: 概述 现状 折线图的应用比较广泛,为了增强用户体验,很多应用中都嵌入了折线图.折线图可以更加直观的表示数据的变化.网络上有很多绘制折线图的demo,有的也使用了动画,但是线条颜色渐变的折线图的demo少之又少,甚至可以说没有.该Blog阐述了动画绘制线条颜色渐变的折线图的实现方案,以及折线图线条颜色渐变的实现原理,并附以完整的示例. 成果 本人已将折线图封装到了一个UIView子类中,并提供了相应的接口.该自定义折线图视图,基本上可以适用于大部分需要集成折线图的项目.若你

  • jQuery实现的背景颜色渐变动画效果示例

    本文实例讲述了jQuery实现的背景颜色渐变动画效果.分享给大家供大家参考,具体如下: 完整实例代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" c

  • Android实现颜色渐变动画效果

    目录 前言 一.Android中插值器TypeEvaluator 二.案例效果实现 1.利用Android自带的颜色插值器ArgbEvaluator 2.看看Android自带颜色插值器ArgbEvaluator核心代码 3.根据ArgbEvaluator的实现来自定义一个颜色插值器 4.使用自己定义的颜色插值器MyColorEvaluator 三.源码 本文实例为大家分享了Android颜色渐变动画效果的实现代码,供大家参考,具体内容如下 前言 案例效果的实现比较简单,利用Android自带的

  • js实现按钮颜色渐变动画效果

    本文实例讲述了js实现按钮颜色渐变动画效果的方法.分享给大家供大家参考.具体如下: 这里演示js实现按钮慢慢变色的方法,鼠标移到按钮上,按钮的背景色就发生变化,是慢慢的变化,点击按钮会打开指定链接,这里主要是演示按钮变色的代码实现方法. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-button-cha-color-animate-codes/ 具体代码如下: <HTML><HEAD><TITLE>按钮慢慢变色&

  • Android TextView渐变颜色和方向及动画效果的设置详解

    GradientTextView Github点我 一个非常好用的库,使用kotlin实现,用于设置TexView的字体 渐变颜色.渐变方向 和 动画效果 添加依赖 之前仓库发布在 jcenter,但是因为它即将不可用,近期已完成迁移.建议大家使用 mavenCentral 的配置. 使用 jcenter implementation 'com.williamyang:gradienttext:1.0.1' 使用 mavenCentral buildscript { repositories {

  • .NET 与树莓派WS28XX 灯带的颜色渐变动画效果的实现

    在上一篇水文中,老周演示了 WS28XX 的基本使用.在文末老周说了本篇介绍颜色渐变动画的简单实现. 在正式开始前,说一下题外话. 第一件事,最近树莓派的价格猛涨,相信有关注的朋友都知道了.所以,如果你不是急着用,可以先别买.或者,可以选择 Raspberry Pi 400,这个配置比 4B 高一点,这个目前价格比较正常.Pi 400 就是那个藏在键盘里的树莓派.其实,官网上面的价格已经调回原来的价格了,只是某宝上的那些 Jian 商,还在涨价. 第二件事,树莓派上的应用是不是可以用 C 来写?

  • jQuery与js实现颜色渐变的方法

    本文实例讲述了jQuery与js实现颜色渐变的方法.分享给大家供大家参考,具体如下: 1.目的 本来想的是 提示用户应该点某个按钮 这个功能,就想着让这个按钮div的边框变成醒目的颜色然后逐渐变白. 在网上搜了搜,本来想使用jQuery的animate,后来发现这个方法只能用来进行长度的渐变.还有就是需要下载jQuery的颜色渐变插件来实现,感觉挺麻烦的,就自己用土办法实现了. 2.原理 先获得初始颜色的rgb,再获得终止颜色的rgb,使用rgb三个数字的差值,从初始颜色的rgb逐渐过渡到终止颜

  • iOS渐变圆环旋转动画CAShapeLayer CAGradientLayer

    iOS渐变圆环旋转动画CAShapeLayer CAGradientLayer shape.gif demo.png - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. CALayer *layer = [CALayer layer]; layer.backgroundColor = [UIColor redColor

  • Android简单实现一个颜色渐变的ProgressBar的方法

    今天看一个教程,看到一个颜色渐变的ProgressBar,觉得有点意思,所以记录一番. 下面这个是效果图 颜色渐变的ProgressBar 看到效果图可能会给人一种使用了高端技术的感觉,其实这个没有那么高深,我们只是简单改变了ProgressBar的样式即可实现,下面说说实现方式. 首先我们简单分析一下: 1 . 上面的样式只是实现了颜色渐变,但它旋转和呈现的方式仍然是一个圆形的ProgressBar. 2 . 这个ProgressBar实现了颜色渐变,我们就需要用到gradient,这个也比较

随机推荐