TechnologiesSwiftUIOrnaments and Glass Effects

OrnamentHoverEffect struct

iOSmacOStvOSwatchOSvisionOS✓ renders

Presents an ornament on hover.

How it works

OrnamentHoverEffect describes how an ornament responds when a person looks at or points toward it, giving the floating control a built-in sense of focus before it's activated. In platforms where input is indirect — such as eye and hand tracking in visionOS — an ornament needs to signal that it is interactive and ready, and this effect supplies that affordance without custom animation code. Reach for it whenever an ornament hosts controls that should feel alive under attention, and let the system handle the highlight, scale, or lift that conveys hover state. Because it conforms to HoverEffect, you select a concrete effect through the same vocabulary you'd use for any other hoverable view.

  1. Group the ornament's controls into a hoverable container

    OrnamentHoverEffect applies to the view the ornament presents, so its controls are first composed into a single shape that can receive focus. Here the playback glyphs Image(systemName: "play.fill"), pause.fill, and forward.fill are laid out in an HStack and given a unified pill backdrop with .background(.regularMaterial, in: Capsule()), producing one cohesive target for the effect.

  2. Apply the effect with hoverEffect(_:)

    The hoverEffect(_:) modifier attaches an OrnamentHoverEffect to the view, telling SwiftUI to react when the container is hovered. In the example .hoverEffect(.lift) installs the effect on the capsule, so the whole control group becomes a hover-aware ornament surface rather than a static decoration.

  3. Choose the response by passing a HoverEffect value

    OrnamentHoverEffect conforms to HoverEffect, and the value you pass selects how the view transforms under attention. .lift raises the control toward the viewer to emphasize focus; the same modifier accepts other built-in effects such as .highlight, letting you match the ornament's hover behavior to its visual weight.

  4. Let the effect drive the shape you defined

    The effect operates on the view's resolved bounds, which is why the surrounding Capsule() and .regularMaterial matter — they define the silhouette OrnamentHoverEffect animates. The trailing .padding() keeps the lifted control clear of nearby content so the hover motion reads cleanly against its container.

Try it — Change .hoverEffect(.lift) to .hoverEffect(.highlight) to swap the raised motion for a surface highlight and compare how each OrnamentHoverEffect reads under focus.

Example & preview

Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.

OrnamentHoverEffect.swift
struct OrnamentHoverEffectDemo: View {
    var body: some View {
        HStack(spacing: 16) {
            Image(systemName: "play.fill")
            Image(systemName: "pause.fill")
            Image(systemName: "forward.fill")
        }
        .font(.title2)
        .padding()
        .background(.regularMaterial, in: Capsule())
        .hoverEffect(.lift)
        .padding()
    }
}
Live preview
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →