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

首先創(chuàng)建一個(gè)CAGradientLayer和幾個(gè)自己喜歡的顏色,讓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,起始點(diǎn)和結(jié)束點(diǎn)分別為CGPoint(x:0, y:0)和CGPoint(x:1, y:1),并設(shè)置讓其在后臺(tái)線程異步繪制,最后添加到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)在運(yùn)行后會(huì)得到下面的結(jié)果:

顏色漸變是做到了,那么如何做到顏色漸變的轉(zhuǎn)換呢?這里還是需要用到CABasicAnimation.
在gradient創(chuàng)建完之后,添加并調(diào)用一個(gè)方法animateGradient,在里面添加一個(gè)keyPath為colors的CABasicAnimation,設(shè)置動(dòng)畫時(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)換動(dòng)畫。但是這里有個(gè)問題就是這里只轉(zhuǎn)換了一次,無法轉(zhuǎn)換多次顏色。那么這里就需要設(shè)置好toValue,讓每次的toValue都不一樣。
創(chuàng)建一個(gè)currentGradient和gradientSet讓VC持有。
var currentGradient: Int = 0 var gradientSet = [[CGColor]]()
在animateGradient中每次調(diào)用的時(shí)候,都對(duì)currentGradient的值進(jìn)行判斷和處理。
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")
這里運(yùn)行后發(fā)現(xiàn)還是不行,還是只有一種顏色的轉(zhuǎn)換,這是因?yàn)檫@里只調(diào)用了一次animateGradient()。那么如何在合適的時(shí)機(jī),也就是動(dòng)畫結(jié)束的時(shí)候再調(diào)用一次animateGradient呢?這里就需要用到CAAnimationDelegate。
在CAAnimationDelegate的animationDidStop方法中重新調(diào)用animateGradient。注意這里的gradient.colors 也要改變,否則就會(huì)一直是[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)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Swift操作Quartz 2D進(jìn)行簡單的繪圖與坐標(biāo)變換的教程
這篇文章主要介紹了Swift操作Quartz 2D進(jìn)行簡單的繪圖與坐標(biāo)變換的教程,Quartz 2D是Core Graphics框架中的一個(gè)重要組件,經(jīng)常被Mac OS或和iOS開發(fā)者用來繪圖,需要的朋友可以參考下2016-04-04
舉例講解Swift編程中switch...case語句的用法
這篇文章主要介紹了Swift編程中switch...case語句的用法,其中fallthrough關(guān)鍵字在switch語句中的使用是重點(diǎn),需要的朋友可以參考下2016-04-04
Swift算法之棧和隊(duì)列的實(shí)現(xiàn)方法示例
Swift語言中沒有內(nèi)設(shè)的棧和隊(duì)列,很多擴(kuò)展庫中使用Generic Type來實(shí)現(xiàn)棧或是隊(duì)列。下面這篇文章就來給大家詳細(xì)介紹了Swift算法之棧和隊(duì)列的實(shí)現(xiàn)方法,需要的朋友可以參考學(xué)習(xí),下面來一起看看吧。2017-03-03

