swift实现颜色渐变以及转换动画-kb88凯时官网登录

来自:网络
时间:2023-07-25
阅读:

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

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

返回顶部
顶部
网站地图