Skip to content

Visual Effects (SwiftUI)

A SwiftUI guide for coding agents. Also covers visualeffect modifier, geometry based effects, scale blur opacity from frame, animate by position ios, scroll driven visual effect.

The visualEffect view modifier applies animatable visual effects that are computed from the view's own layout. Its closure hands you a GeometryProxy, so an effect can depend on the frame without a GeometryReader wrapper. Introduced at WWDC 23, iOS 17+.

The Effect Closure

The closure receives the initial effect state (an EmptyVisualEffect) and a GeometryProxy with the frame, size, and safe area. Chain effects onto the initial value and return the result.

Text("Hello World!")
  .visualEffect { initial, geometry in
    initial.offset(geometry.size)
  }

What Counts as a Visual Effect

A visual effect changes how the view looks without changing its layout. scaleEffect, offset, blur, contrast, saturation, opacity, and rotationEffect all conform to the VisualEffect protocol and chain inside the closure.

Text("Hello World!")
  .visualEffect { initial, geometry in
    initial
      .blur(radius: 8)
      .opacity(0.9)
      .scaleEffect(.init(width: 2, height: 2))
  }

frame and padding are not visual effects. They change layout, so they cannot appear inside the closure.

Animating It

The effects are animatable. Drive them from state and attach animation as usual.

Text("Hello World!")
  .visualEffect { initial, geometry in
    initial.scaleEffect(
      CGSize(width: isScaled ? 2 : 1, height: isScaled ? 2 : 1)
    )
  }
  .animation(.smooth, value: isScaled)

When to Use It

Reach for visualEffect only when the effect depends on layout information. When it does not, the plain modifiers (opacity, offset, scaleEffect) do the same job and run on older OS versions.

Use this guidance in your coding agent

Install the Better Design MCP once. Your agent then loads this page with one call.

get-swiftui-guide({ topic: "swiftui-visual-effects" })
claude mcp add --scope user better-design --transport http https://better-design.com/api/mcp --header "Authorization: Bearer <YOUR_API_KEY>"
Browse related design systems