swift實現(xiàn)顏色漸變以及轉(zhuǎn)換動畫
本文是通過結(jié)合使用CAGradientLayer、CABasicAnimation以及CAAnimationDelegate來達到顏色漸變以及轉(zhuǎn)換的動畫,下面是今天要達成的效果圖:

首先創(chuàng)建一個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等同于視圖的大小,然后顏色先設(shè)置為colorOne和colorTwo,起始點和結(jié)束點分別為CGPoint(x:0, y:0)和CGPoint(x:1, y:1),并設(shè)置讓其在后臺線程異步繪制,最后添加到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)
現(xiàn)在運行后會得到下面的結(jié)果:

顏色漸變是做到了,那么如何做到顏色漸變的轉(zhuǎn)換呢?這里還是需要用到CABasicAnimation.
在gradient創(chuàng)建完之后,添加并調(diào)用一個方法animateGradient,在里面添加一個keyPath為colors的CABasicAnimation,設(shè)置動畫時長為3s,設(shè)置結(jié)束值等一系列屬性。
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")
? ? ? }這里就完成了轉(zhuǎn)換動畫。但是這里有個問題就是這里只轉(zhuǎn)換了一次,無法轉(zhuǎn)換多次顏色。那么這里就需要設(shè)置好toValue,讓每次的toValue都不一樣。
創(chuàng)建一個currentGradient和gradientSet讓VC持有。
var currentGradient: Int = 0 var gradientSet = [[CGColor]]()
在animateGradient中每次調(diào)用的時候,都對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")
這里運行后發(fā)現(xiàn)還是不行,還是只有一種顏色的轉(zhuǎn)換,這是因為這里只調(diào)用了一次animateGradient()。那么如何在合適的時機,也就是動畫結(jié)束的時候再調(diào)用一次animateGradient呢?這里就需要用到CAAnimationDelegate。
在CAAnimationDelegate的animationDidStop方法中重新調(diào)用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()
? ? ? ? }
? ? }
? ??
}以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot3.0集成Redis緩存的實現(xiàn)示例
緩存就是一個存儲器,常用 Redis作為緩存數(shù)據(jù)庫,本文主要介紹了SpringBoot3.0集成Redis緩存的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下2024-03-03
Objective-c代碼如何移植為Swift代碼 Objective-c代碼轉(zhuǎn)移到Swift過程介紹
這篇文章主要介紹了Objective-c代碼如何移植為Swift代碼,Objective-c代碼轉(zhuǎn)移到Swift過程介紹,需要的朋友可以參考下2014-07-07
用Swift構(gòu)建一個簡單的iOS郵件應(yīng)用的方法
這篇文章主要介紹了用Swift構(gòu)建一個簡單的iOS郵件應(yīng)用的方法,包括查看和標記已讀等基本的郵件應(yīng)用功能,需要的朋友可以參考下2015-07-07

