An Apple Intelligence-Style Glow Effect in SwiftUI


Greetings, traveler!

Apple’s recent design language introduces a glowing, animated stroke effect that highlights shapes and components in a subtle yet dynamic way. Let’s walk through how to recreate this effect in SwiftUI with reusable extensions.

Extending View with Background and Overlay

The first step is to make the glow effect easy to apply anywhere. Two modifiers are provided: one for background and one for overlay.

extension View {
    @MainActor
    func intelligenceBackground<S: InsettableShape>(
        in shape: S
    ) -> some View {
        background(
            shape.intelligenceStroke()
        )
    }
    
    @MainActor
    func intelligenceOverlay<S: InsettableShape>(
        in shape: S
    ) -> some View {
        overlay(
            shape.intelligenceStroke()
        )
    }
}

Both rely on the same underlying stroke renderer, but give flexibility depending on the layout.

Adding the Glow Stroke to Shapes

The core work happens in a custom stroke method on InsettableShape. This allows any shape—such as Capsule, Rectangle, or Circle—to render with a glowing animated border.

extension InsettableShape {
    @MainActor
    func intelligenceStroke(
        lineWidths: [CGFloat] = [6, 9, 11, 15],
        blurs: [CGFloat] = [0, 4, 12, 15],
        updateInterval: TimeInterval = 0.4,
        animationDurations: [TimeInterval] = [0.5, 0.6, 0.8, 1.0],
        gradientGenerator: @MainActor @Sendable @escaping () -> [Gradient.Stop] = { .intelligenceStyle }
    ) -> some View {
        IntelligenceStrokeView(
            shape: self,
            lineWidths: lineWidths,
            blurs: blurs,
            updateInterval: updateInterval,
            animationDurations: animationDurations,
            gradientGenerator: gradientGenerator
        )
        .allowsHitTesting(false)
    }
}

This method wraps the actual rendering logic into a dedicated view.

Rendering the Stroke Layers

The IntelligenceStrokeView applies multiple gradient stroke layers, each with its own line width, blur, and animation timing. Together, they create a soft glowing halo that animates over time.

private struct IntelligenceStrokeView<S: InsettableShape>: View {
    let shape: S
    let lineWidths: [CGFloat]
    let blurs: [CGFloat]
    let updateInterval: TimeInterval
    let animationDurations: [TimeInterval]
    let gradientGenerator: @MainActor @Sendable () -> [Gradient.Stop]

    @Environment(\.accessibilityReduceMotion) private var reduceMotion
    @State private var stops: [Gradient.Stop] = .intelligenceStyle

    var body: some View {
        let layerCount = min(lineWidths.count, blurs.count, animationDurations.count)
        let gradient = AngularGradient(
            gradient: Gradient(stops: stops),
            center: .center
        )

        ZStack {
            ForEach(0..<layerCount, id: \.self) { i in
                shape
                    .strokeBorder(gradient, lineWidth: lineWidths[i])
                    .blur(radius: blurs[i])
                    .animation(
                        reduceMotion ? .linear(duration: 0) : easeInOut(duration: animationDurations[i]),
                        value: stops
                    )
            }
        }
        .task(id: updateInterval) {
            while !Task.isCancelled {
                stops = gradientGenerator()
                try? await Task.sleep(for: .seconds(updateInterval))
            }
        }
    }
}

Each iteration of the loop draws one layer of the glow, blurred differently to give depth. The gradient stops are regenerated periodically, producing the animated “flowing” effect.

Gradient Palette

The glow effect depends on a palette of soft, vibrant colors. These are randomized slightly in their positions to make the animation look organic.

private extension Array where Element == Gradient.Stop {
    static var intelligenceStyle: [Gradient.Stop] {
        [
            Color(red: 188/255, green: 130/255, blue: 243/255),
            Color(red: 245/255, green: 185/255, blue: 234/255),
            Color(red: 141/255, green: 159/255, blue: 255/255),
            Color(red: 255/255, green: 103/255, blue: 120/255),
            Color(red: 255/255, green: 186/255, blue: 113/255),
            Color(red: 198/255, green: 134/255, blue: 255/255)
        ]
        .map { Gradient.Stop(color: $0, location: Double.random(in: 0...1)) }
        .sorted { $0.location < $1.location }
    }
}

Usage Examples

Applying the glow is simple:

VStack(spacing: 30) {
    Text("Some text here")
        .padding(22)
        .intelligenceBackground(in: .capsule)

    Text("Some text here")
        .padding(22)
        .intelligenceOverlay(in: .rect(cornerRadius: 22))
}

The first example places the glow behind the capsule, while the second renders it as an overlay above the rectangle.

Conclusion

This implementation shows how to combine multiple strokes, blurs, and animated gradients to achieve a glow effect similar to Apple’s Intelligence UI. The result works with any InsettableShape. It can be used to highlight buttons, cards, or text containers in a modern, expressive way.

Swift Package on GitHub: https://github.com/Livsy90/IntelligenceGlow/tree/main