I have a view that looks like this:
I would like to animate the gradient in the listRowBackground, but I am not able to for some reason. Here is the code I have:
import SwiftUI
struct SnakeColorView: View {
@AppStorage("HeadColor") private var HeadColor : Color = .white
@AppStorage("BodyColor") private var BodyColor : Color = .white
@State private var animateGradient : Bool = false
var body: some View {
let bgGradient = LinearGradient(colors: [Color("Bi Pink"), Color("Bi Purple"), Color("Bi Blue")], startPoint: animateGradient ? .top : .bottom, endPoint: animateGradient ? .bottom : .top)
List {
ColorPicker("Set the color of the Snake's head!!", selection: $HeadColor)
ColorPicker("Set the color of the Snake's body!!", selection: $BodyColor)
HStack{
Spacer()
VStack(spacing: 0) {
ZStack{
Ellipse()
.fill(HeadColor)
Ellipse()
.strokeBorder(.white, lineWidth: 3.2)
}.frame(width: 100, height: 175)
ForEach(0..<7) { _ in
ZStack {
Circle()
.fill(BodyColor)
Circle()
.strokeBorder(.white, lineWidth: 3.2)
}
}.frame(width: 50, height: 50)
}
Spacer()
}
.listRowBackground(bgGradient)
.ignoresSafeArea()
.onAppear {
withAnimation(.linear(duration: 2.0).repeatForever(autoreverses: true)) {
animateGradient.toggle()
}
}
}
}
}
I have the state variable for the animation, and it should be triggered by onAppear but nothing happens.
Add .animation
property with value
to explicitly telling LinearGradient
what animation to use when animateGradient
value changes. The following code with output:
Code:
@State private var animateGradient : Bool = false
var body: some View {
let bgGradient = LinearGradient(colors: [Color.pink, Color.purple, Color.blue], startPoint: animateGradient ? .topLeading : .bottomTrailing, endPoint: animateGradient ? .bottomTrailing : .topLeading)
List {
HStack{
Spacer()
VStack(spacing: 0) {
ZStack{
Ellipse()
.fill(Color.red)
Ellipse()
.strokeBorder(.white, lineWidth: 3.2)
}.frame(width: 100, height: 175)
ForEach(0..<7) { _ in
ZStack {
Circle()
.fill(Color.yellow)
Circle()
.strokeBorder(.white, lineWidth: 3.2)
}
}.frame(width: 50, height: 50)
}
Spacer()
}
.listRowBackground(
bgGradient
.animation(.linear(duration: 5.0).repeatForever(autoreverses: true), value: animateGradient) // ---> add animation
)
.ignoresSafeArea()
.onAppear {
animateGradient.toggle() // --> toggle value
}
}
}
Output: