LinearGradient and RadialGradient only interpolate along a line or out from a single center point. Any background that needed several independent color regions blending organically — the kind of look Apple uses in Control Center and widget backgrounds — meant reaching for a custom Metal shader or faking it with layered, blurred shapes.
#The old way
ZStack {
Color.indigo
Circle().fill(.purple).blur(radius: 80).offset(x: -100, y: -150)
Circle().fill(.pink).blur(radius: 80).offset(x: 120, y: 100)
Circle().fill(.orange).blur(radius: 80).offset(x: -80, y: 150)
}
.ignoresSafeArea()
Approximate, expensive to blur at full screen size, and impossible to animate smoothly without independent state for every circle.
#The new way
import SwiftUI
import Foundation
struct MeshBackground: View {
var body: some View {
TimelineView(.animation) { timeline in
let t = timeline.date.timeIntervalSinceReferenceDate
MeshGradient(
width: 3,
height: 3,
points: [
[0, 0], [0.5, 0], [1, 0],
[0, 0.5], [Float(0.5 + 0.15 * sin(t)), Float(0.5 + 0.15 * cos(t))], [1, 0.5],
[0, 1], [0.5, 1], [1, 1]
],
colors: [
.indigo, .purple, .pink,
.blue, .white, .orange,
.teal, .green, .yellow
]
)
.ignoresSafeArea()
}
}
}
TimelineView(.animation) redraws every frame, so the center control point drifts in a small circle and the mesh continuously reshapes itself with zero manual animation code.
#Why it matters
- GPU-driven interpolation between arbitrary control points, not a fixed line or radius
- Fully declarative and animatable — drive
pointsorcolorsfrom state, aTimelineView, or both - One view replaces what used to require a custom shader or several blurred, layered shapes
#Gotcha
The points array count must exactly equal width * height — a 3×3 mesh needs exactly 9 points, in row-major order. Get the count wrong and it traps at runtime, not a silent visual glitch. It's also easy to accidentally drag a corner or edge point away from its pinned axis (0, 0.5, 1) while animating the interior — that folds the mesh and produces a visible seam instead of a smooth gradient.