Linear, Radial, and Angular Gradients in SwiftUI | SwiftUI Bootcamp #5
Gradients turn flat color fills into rich, dynamic backgrounds that give apps depth and visual personality. After this lesson you'll be able to create all three gradient types in SwiftUI and understand how to control their direction, center point, and angle.
What You'll Learn
- The three gradient types:
LinearGradient,RadialGradient, andAngularGradient - How
startPoint/endPoint,center/startRadius/endRadius, andanglecontrol each type - Why gradients conform to
ShapeStyleand can be used anywhere aColorcan
Mental Model
Imagine three different types of spotlights pointed at a wall. A LinearGradient is a soft edge light that fades from one side to the other in a straight line — like sunlight coming through a window and fading across a room. A RadialGradient is a spotlight pointed directly at the wall — bright in the center, fading outward in all directions like a halo. An AngularGradient is a spotlight spinning in a circle — the color changes as you sweep around a center point, like the color wheel on a color picker.
All three use the same Gradient(colors:) type to describe the color stops, but differ only in how those colors are distributed across space.
Detailed Explanation
All three gradient types conform to ShapeStyle, which means you can use them anywhere SwiftUI accepts a Color: inside .fill(), .background(), .foregroundStyle(), and more.
LinearGradient takes a startPoint and endPoint using SwiftUI's UnitPoint constants: .top, .bottom, .leading, .trailing, .topLeading, .bottomTrailing, etc. The gradient interpolates smoothly between colors along that axis. For diagonal gradients (common in card backgrounds), use .topLeading to .bottomTrailing.
RadialGradient radiates outward from a center point. startRadius is the distance from center where the first color starts; endRadius is where the last color ends. Any area beyond endRadius continues with the last color stop.
AngularGradient sweeps colors around a center point like clock hands. The angle parameter sets the starting angle (0° is pointing right, 90° is pointing down). It's the gradient used in color wheels and conic progress indicators.
You can define multiple color stops by passing more colors to Gradient(colors:), and you can add intermediate Gradient.Stop values with specific percentages (stops: [.init(color: .blue, location: 0.3)]) for fine-grained control.
Code Structure
The sample is in GradientsBootcamp.swift and uses AngularGradient as the active fill. The commented code above it shows LinearGradient and RadialGradient equivalents using the same color pair. Swap between them to see how the same two colors distribute differently depending on the gradient type.
Complete Code
GradientsBootcamp.swift
import SwiftUI
struct GradientsBootcamp: View {
var body: some View {
RoundedRectangle(cornerRadius: 25.0)
.fill(
//Color.red // plain fill for comparison
// LinearGradient(
// gradient: Gradient(colors: [Color(#colorLiteral(red: 0.2392156869, green: 0.6745098233, blue: 0.9686274529, alpha: 1)), Color(#colorLiteral(red: 0.1411764771, green: 0.3960784376, blue: 0.5647059083, alpha: 1))]),
// startPoint: .topLeading, // gradient starts at the top-left corner
// endPoint: .bottom) // and ends at the bottom center
// RadialGradient(
// gradient: Gradient(colors: [Color(#colorLiteral(red: 0.2392156869, green: 0.6745098233, blue: 0.9686274529, alpha: 1)), Color(#colorLiteral(red: 0.1411764771, green: 0.3960784376, blue: 0.5647059083, alpha: 1))]),
// center: .leading, // origin point of the radial spread (left-center)
// startRadius: 5, // the lighter color begins 5pt from center
// endRadius: 400) // the darker color is fully applied 400pt from center
AngularGradient(
gradient: Gradient(colors: [Color(#colorLiteral(red: 0.2392156869, green: 0.6745098233, blue: 0.9686274529, alpha: 1)), Color(#colorLiteral(red: 0.1411764771, green: 0.3960784376, blue: 0.5647059083, alpha: 1))]),
center: .topLeading, // the sweep rotates around the top-left corner
angle: .degrees(180 + 45)) // starts the sweep at 225° (bottom-left direction)
)
.frame(width: 300, height: 200) // fixes the card size so the gradient is visible
}
}
struct GradientsBootcamp_Previews: PreviewProvider {
static var previews: some View {
GradientsBootcamp()
}
}Code Walkthrough
Gradient(colors:)— A shared type used by all three gradient variants. It accepts an array ofColorvalues and distributes them evenly across the gradient. The sameGradientdefinition is reused in all three commented examples — only the gradient type wrapper changes.LinearGradient(gradient:startPoint:endPoint:)—startPoint: .topLeadingplaces the first color at the top-left.endPoint: .bottommakes the second color land at the bottom-center. Diagonal gradients are common for cards and hero images.RadialGradient(gradient:center:startRadius:endRadius:)— The gradient radiates outward fromcenter.startRadius: 5means the inner color fills almost all the way from the center dot outward, creating a tight core. IncreasestartRadiusto push the transition further out.AngularGradient(gradient:center:angle:)— Theanglevalue offsets where the gradient starts its sweep..degrees(180 + 45)= 225°, which points the sweep toward the bottom-left. Adjusting this angle rotates the color transition around thecenterpoint.center: .topLeading— ForAngularGradient, the center is the pivot point of the sweep, not the visual center. Placing it at.topLeadingcreates a fan effect from the top-left corner, which produces a dramatic corner-lit look..frame(width: 300, height: 200)— Gradients expand to fill available space if unconstrained. A fixed frame makes the gradient behavior predictable during development.
Common Mistakes
Mistake: Using AngularGradient when you want a simple diagonal fillAngularGradient sweeps colors around a point — it's for conic/cone effects. For a simple top-to-bottom or diagonal fill, use LinearGradient. Using the wrong gradient type for a design intent is a common beginner confusion because the names aren't immediately intuitive.
Mistake: Passing only one color to Gradient(colors:) A single-color gradient is just a flat fill — there's nothing to interpolate. You need at least two color values. For a three-stop gradient (e.g., fade to clear in the middle), pass three colors: [.blue, .clear, .blue].
Mistake: Expecting RadialGradient to stay circular in non-square framesRadialGradient uses the view's coordinate space, which means in a wide rectangular frame, the radial circle is stretched into an ellipse. If you need a perfect circle gradient, constrain the frame to a square or apply the gradient to a Circle shape.
Key Takeaways
LinearGradientis for directional fades;RadialGradientfor center-outward halos;AngularGradientfor conic sweeps- All three gradient types conform to
ShapeStyleand work inside.fill(),.background(), and.foregroundStyle() - The
Gradient(colors:)definition is shared across all three types — only the wrapping gradient type and its geometry parameters change
Last updated: June 27, 2026