AngularGradient view in SwiftUI was introduced with iOS 13 and is used to draw an angular gradient. This view conforms to ShapeStyle protocol.
For the simplest initializer AngularGradient takes colors as a parameter along with UnitPoint for the location of center as shown below:
struct AngularGradientExample: View {
let colors = [Color.blue, .purple, .cyan, .teal, .green, .orange, .pink, .red]
var body: some View {
AngularGradient(colors: colors, center: .center)
.edgesIgnoringSafeArea(.all)
}
}
We can move center by changing the value for center.
struct AngularGradientExample: View {
let colors = [Color.blue, .purple, .cyan, .teal, .green, .orange, .pink, .red]
var body: some View {
AngularGradient(colors: colors, center: .topLeading)
.edgesIgnoringSafeArea(.all)
}
}
Instead of typing all enum values for UnitPoint, we will animate between them.
struct AngularGradientExample: View {
let colors = [Color.blue, .purple, .cyan, .teal, .green, .orange, .pink, .red] let unitPoints = [UnitPoint.top, .topLeading, .center, .bottom, .bottomLeading, .bottomTrailing, .topTrailing, .trailing, .leading] @State private var centerLocation = UnitPoint.center let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
AngularGradient(colors: colors, center: centerLocation)
.edgesIgnoringSafeArea(.all)
.animation(Animation.easeInOut.speed(0.5), value: centerLocation)
.onReceive(timer) { input in
centerLocation = unitPoints.randomElement() ?? .center
}
}
}
By combining ZStack and Material, we can even create an interesting background effect as shown below:
struct AngularGradientExample: View {
let colors = [Color.blue, .purple, .cyan, .teal] let unitPoints = [UnitPoint.top, .topLeading, .center, .bottom, .bottomLeading, .bottomTrailing, .topTrailing, .trailing, .leading] @State private var centerLocation = UnitPoint.center let timer = Timer.publish(every: 2, on: .main, in: .common).autoconnect()
var body: some View {
ZStack {
AngularGradient(colors: colors, center: centerLocation)
.edgesIgnoringSafeArea(.all)
.animation(Animation.easeInOut.speed(0.1), value: centerLocation)
.onReceive(timer) { input in
centerLocation = unitPoints.randomElement() ?? .center
}
VStack {
Text("DevTechie")
.font(.largeTitle)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.thinMaterial)
}
}
}
UnitPoint can take point values as well so instead of selecting from an enum, we can define UnitPoint in terms of values for x and y.
struct AngularGradientExample: View {
let colors = [Color.blue, .purple, .cyan, .teal]
@State private var centerLocation = UnitPoint.center
let timer = Timer.publish(every: 2, on: .main, in: .common).autoconnect()
var body: some View {
ZStack {
AngularGradient(colors: colors, center: centerLocation)
.edgesIgnoringSafeArea(.all)
.animation(Animation.easeInOut.speed(0.1), value: centerLocation)
.onReceive(timer) { input in
centerLocation = UnitPoint(x: CGFloat.random(in: 0...1), y: CGFloat.random(in: 0...1))
}
}
}
}
AngularGradient comes with start and end angle. Angle can be defined in degree and radian. We will use degree value for our case.
struct AngularGradientExample: View {
let colors = [Color.blue, .purple, .cyan, .teal]
@State private var centerLocation = UnitPoint.center
@State private var startAngle = Angle(degrees: 90.0)
@State private var endAngle = Angle(degrees: 360.0)
let timer = Timer.publish(every: 2, on: .main, in: .common).autoconnect()
var body: some View {
ZStack {
AngularGradient(colors: colors, center: centerLocation, startAngle: startAngle, endAngle: endAngle)
.edgesIgnoringSafeArea(.all)
.animation(Animation.easeInOut.speed(0.1), value: centerLocation)
.onReceive(timer) { input in
centerLocation = UnitPoint(x: CGFloat.random(in: 0...1), y: CGFloat.random(in: 0...1))
startAngle = Angle(degrees: Double.random(in: 1...180))
endAngle = Angle(degrees: Double.random(in: 0...360))
}
}
}
}
So far we have seen examples of setting values for center, start and end angle for AngularGradient view but there is one more aspect that you can control for this view.
AngularGradient allows you to control the color stop, essentially you can define where one color should stop and another one should begin. For this purpose, AngularGradient has an overloaded initializer which takes Gradient.Stop array value as shown below: