TechnologiesSwiftUIAccessibility

AccessibilityZoomGestureAction struct

iOSmacOStvOSwatchOSvisionOSiOS 16.0+✓ renders

Position and direction information of a zoom gesture that someone performs

How it works

AccessibilityZoomGestureAction describes a zoom request that assistive technologies — such as VoiceOver or Switch Control — perform on your behalf when a user wants to magnify or shrink content. Many views convey scale through direct pinch gestures that aren't available to people relying on assistive technology, so SwiftUI surfaces that intent as a structured action instead. When you register a zoom handler on an accessibility element, the system hands you an AccessibilityZoomGestureAction value describing whether the user asked to zoom in or out, leaving you to update your own state in response. Reach for it whenever a view supports scaling and you want that capability to be operable without a physical pinch.

  1. Register a handler with accessibilityZoomAction(_:)

    The accessibilityZoomAction modifier attaches a closure to an accessibility element that the system invokes when assistive technology requests a zoom. SwiftUI calls the closure with a single AccessibilityZoomGestureAction parameter — named action in the example — each time the user triggers a magnify or shrink command.

  2. Branch on the action's direction property

    Each AccessibilityZoomGestureAction exposes a direction describing the requested change. The example switches over it to separate the two intents, so you respond to a zoom-in differently than a zoom-out rather than treating every request the same.

  3. Handle the Direction cases: zoomIn and zoomOut

    direction is an AccessibilityZoomGestureAction.Direction, an enumeration whose zoomIn and zoomOut cases tell you which way to scale. Here .zoomIn increases magnification by 0.5, while .zoomOut decreases it but clamps the floor with max(1.0, magnification - 0.5); an @unknown default case keeps the switch resilient to future directions.

  4. Drive view state from the action

    The handler's job is to translate the abstract zoom request into a concrete change in your own model. Writing to the @State property magnification — which feeds scaleEffect(magnification) — lets the action re-render the view, so an assistive-technology zoom produces the same visible result a pinch would.

  5. Make the target a single accessibility element

    The zoom action belongs on something the accessibility system recognizes as one focusable item. Calling accessibilityElement() (and labeling it with accessibilityLabel("Zoomable map")) gives VoiceOver a discrete element to focus, which is what receives the AccessibilityZoomGestureAction when the user issues a zoom command.

Try it — Change the .zoomIn branch from magnification += 0.5 to magnification += 2.0 and trigger a zoom-in with VoiceOver to watch a single assistive-technology zoom request jump the scale far more sharply.

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.

AccessibilityZoomGestureAction.swift
struct AccessibilityZoomGestureActionDemo: View {
    @State private var magnification = 1.0

    var body: some View {
        VStack(spacing: 16) {
            Text("Map")
                .font(.largeTitle)
                .scaleEffect(magnification)
                .frame(width: 200, height: 200)
                .background(.blue.opacity(0.2))
                .accessibilityElement()
                .accessibilityLabel("Zoomable map")
                .accessibilityZoomAction { action in
                    switch action.direction {
                    case .zoomIn:  magnification += 0.5
                    case .zoomOut: magnification = max(1.0, magnification - 0.5)
                    @unknown default: break
                    }
                }

            Text("Magnification: \(magnification, specifier: "%.1f")x")
                .font(.headline)
        }
        .padding()
    }
}
Live preview
Map Magnification: 1.0x
Map Magnification: 1.0x
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →