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

 更新时间:2022年01月26日 11:07:56   作者:LinShunIos  
这篇文章主要为大家详细介绍了swift实现颜色渐变以及转换动画,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

本文是通过结合使用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()
? ? ? ? }
? ? }
? ??
}

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

相关文章

  • Swift语言中的一些访问控制设置详解

    Swift语言中的一些访问控制设置详解

    这篇文章主要介绍了Swift语言中的一些访问控制设置详解,是Swift入门学习中的基础知识,需要的朋友可以参考下
    2015-11-11
  • Swift中排序算法的简单取舍详解

    Swift中排序算法的简单取舍详解

    对于排序算法, 通常简单的, 为大家所熟知的有, 选择排序, 冒泡排序, 快速排序, 当然还有哈希, 桶排序之类的, 本文仅比较最为常见的选择, 冒泡和快排,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2018-03-03
  • Swift中字典与JSON转换的方法

    Swift中字典与JSON转换的方法

    Swift中经常会遇到字典和字符串的相互转换,本篇文章主要介绍了Swift中字典与JSON转换的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-03-03
  • SpringBoot3.0集成Redis缓存的实现示例

    SpringBoot3.0集成Redis缓存的实现示例

    缓存就是一个存储器,常用 Redis作为缓存数据库,本文主要介绍了SpringBoot3.0集成Redis缓存的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Objective-c代码如何移植为Swift代码 Objective-c代码转移到Swift过程介绍

    Objective-c代码如何移植为Swift代码 Objective-c代码转移到Swift过程介绍

    这篇文章主要介绍了Objective-c代码如何移植为Swift代码,Objective-c代码转移到Swift过程介绍,需要的朋友可以参考下
    2014-07-07
  • Swift图像处理之优化照片

    Swift图像处理之优化照片

    Core Image能通过分析图片的各个属性,人脸的区域等进行自动优化图片。我们只需要调用autoAdjustmentFiltersWithOptions这个API方法获取各个自动增强滤镜来优化图片即可。不管是人物照片还是风景照均可增强效果
    2015-11-11
  • 用Swift构建一个简单的iOS邮件应用的方法

    用Swift构建一个简单的iOS邮件应用的方法

    这篇文章主要介绍了用Swift构建一个简单的iOS邮件应用的方法,包括查看和标记已读等基本的邮件应用功能,需要的朋友可以参考下
    2015-07-07
  • Swift协议Protocol介绍

    Swift协议Protocol介绍

    协议规定了用来实现某一特定功能所必需的方法和属性。任意能够满足协议要求的类型被称为遵循(conform)这个协议。类,结构体或枚举类型都可以遵循协议,并提供具体实现来完成协议定义的方法和功能
    2022-08-08
  • Swift中的HTTP模拟测试示例详解

    Swift中的HTTP模拟测试示例详解

    这篇文章主要为大家介绍了Swift中的HTTP模拟测试示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • Swift源码解析之弱引用

    Swift源码解析之弱引用

    这篇文章主要给大家介绍了关于Swift源码解析之弱引用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03

最新评论

?


http://www.vxiaotou.com