What You Will Build

Two card styles with continuously rotating rainbow borders: one with a solid gradient stroke, and one with a dashed rotating border. These animated borders are used for highlighting premium content, active selections, or loading states on cards and containers.

Why This Pattern Matters

Animated borders draw attention without being as heavy as full-card animations. This technique is widely used in gaming UIs, subscription prompts, and file upload zones. It teaches you AngularGradient rotation and the difference between solid and dashed strokes.

Key SwiftUI Concepts

  • AngularGradient creates a circular rainbow that sweeps around a center point.
  • Rotation angle animation with .repeatForever(autoreverses: false) for continuous spinning.
  • StrokeStyle with dash pattern for the dashed variant.

Step 1: The Solid Rotating Border

struct BorderAnimationDemo: View {
    @State private var rotation: Double = 0

    var body: some View {
        VStack(spacing: 40) {
            // Solid rotating border card
            RoundedRectangle(cornerRadius: 20)
                .fill(.black)
                .frame(width: 250, height: 150)
                .overlay {
                    Text("Animated Border")
                        .font(.headline)
                        .foregroundStyle(.white)
                }
                .overlay {
                    RoundedRectangle(cornerRadius: 20)
                        .stroke(
                            AngularGradient(
                                colors: [.blue, .purple, .pink,
                                         .red, .orange, .yellow,
                                         .green, .blue],
                                center: .center,
                                angle: .degrees(rotation)
                            ),
                            lineWidth: 3
                        )
                }
        }
        .onAppear {
            withAnimation(.linear(duration: 3)
                .repeatForever(autoreverses: false)) {
                rotation = 360
            }
        }
    }
}

Step 2: The Dashed Variant

For a dashed rotating border, use the same approach but with a StrokeStyle that includes a dash pattern. Notice that the dashed variant uses rotation * 2 to spin faster:

RoundedRectangle(cornerRadius: 20)
    .fill(.black)
    .frame(width: 250, height: 150)
    .overlay {
        Text("Dashed Border")
            .font(.headline)
            .foregroundStyle(.white)
    }
    .overlay {
        RoundedRectangle(cornerRadius: 20)
            .stroke(
                AngularGradient(
                    colors: [.cyan, .blue, .purple, .cyan],
                    center: .center,
                    angle: .degrees(rotation * 2)
                ),
                style: StrokeStyle(lineWidth: 3, dash: [10, 5])
            )
    }

How AngularGradient Rotation Works

An AngularGradient distributes colors in a circle around its center. The angle parameter offsets where the gradient starts. By animating this angle from 0 to 360 degrees, the entire rainbow sweeps around the border continuously.

Tips and Pitfalls

  • autoreverses: false is essential for seamless looping. With autoreverses, the border would spin forward then backward.
  • Match first and last colors in the gradient array (e.g., both .blue) to avoid a visible seam.
  • lineWidth affects performance: Thick borders with blur or shadow on top can be expensive. Keep lineWidth at 2-4.
  • Dash pattern [10, 5] means 10 points drawn, 5 points gap. Adjust for denser or sparser dashes.

iOS Version: iOS 15+

Get New Tutorials by Email

No spam. Just clear, practical breakdowns you can apply right away.

Enjoy this tutorial?

Get new practical tech tutorials in your inbox.