Animate LinearGradient on state change in SwiftUI

Created Aug 23 2020

SWIFT
1
import SwiftUI
2
3
// Based on https://nerdyak.tech/development/2019/09/30/animating-gradients-swiftui.html
4
5
extension Color {
6
static func random()->Color {
7
let r = Double.random(in: 0 ... 1)
8
let g = Double.random(in: 0 ... 1)
9
let b = Double.random(in: 0 ... 1)
10
return Color(red: r, green: g, blue: b)
11
}
12
}
13
14
struct ContentView: View {
15
@State private var gradientA: [Color] = [.red, .purple]
16
@State private var gradientB: [Color] = [.red, .purple]
17
@State private var selected = 0
18
@State private var firstPlane: Bool = true
19
20
func setGradient(gradient: [Color]) {
21
if firstPlane {
22
gradientB = gradient
23
}
24
else {
25
gradientA = gradient
26
}
27
firstPlane = !firstPlane
28
}
29
30
31
var body: some View {
32
ZStack {
33
34
Rectangle().fill(LinearGradient(gradient: Gradient(colors: self.gradientA), startPoint: .topLeading, endPoint: .bottomLeading)).edgesIgnoringSafeArea(.all)
35
Rectangle().fill(LinearGradient(gradient: Gradient(colors: self.gradientB), startPoint: .topLeading, endPoint: .bottomLeading)).edgesIgnoringSafeArea(.all)
36
.opacity(self.firstPlane ? 0 : 1)
37
38
TabView(selection: $selected){
39
Text("☀️").font(.title).tag(0)
40
Text("🌦").font(.title).tag(1)
41
Text("⛈").font(.title).tag(2)
42
}.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
43
.tabViewStyle(PageTabViewStyle())
44
}.onChange(of: selected) { newselected in
45
print("\(newselected)!")
46
withAnimation (.easeInOut(duration: 0.7)){
47
self.setGradient(gradient: [Color.random(), Color.random()])
48
}
49
}
50
}
51
}
52
53
struct ContentView_Previews: PreviewProvider {
54
static var previews: some View {
55
ContentView()
56
}
57
}