Ensure Visual Accessibility: Supporting reduced motion preferences in SwiftUI

Ensure Visual Accessibility: Supporting reduced motion preferences in SwiftUI

Understand how to use the system reduce motion preference to make your animations accessible within SwiftUI

Animations in apps are handy for conveying status, providing feedback, and enhancing the visual experience of an app. However, Human Interface Guidelines (HIG) suggest using them carefully because certain users may encounter discomfort or cognitive challenges with animations.

iOS offers users accessibility settings to control motion effects, such as the “Reduce Motion” option. This setting is essential for users with motion sensitivity or other conditions that make animations uncomfortable or disorienting. As developers, we must design the best experience for everyone.

Implementing Reduce Motion in SwiftUI

SwiftUI makes it easy to respect these user preferences through environment values:

import SwiftUI

enum AnimationPhase: CaseIterable {
    case initial
    case middle
    case end
    
    var animationValue: CGSize {
        switch self {
        case .initial: CGSize(width: 1, height: 1)
        case .middle: CGSize(width: 0.5, height: 0.5)
        case .end: CGSize(width: 1.5, height: 1.5)
        }
    }
}

struct ContentView: View {
    // Environment value storing the user system preference
    @Environment(\.accessibilityReduceMotion) var isReduceMotionEnabled
    
    @State private var scale = CGSize(width: 1, height: 1)
    
    var body: some View {
        PhaseAnimator(AnimationPhase.allCases) { phase in
            VStack {
                Circle()
                    .fill(Color.blue)
                    .frame(width: 100, height: 100)
                    .scaleEffect(isReduceMotionEnabled ? scale : phase.animationValue)
            }
        }
        
    }
}

The environment values are key to making our animations accessible. With @Environment(\.accessibilityReduceMotion) we can read the user's system preference for reduced motion. In the example above the scale property maintains the same size when animation are disabled in the system, respecting accessibility preferences.

You can test the behavior of the "Reduce Motion" setting in Xcode's accessibility inspector or by toggling the setting directly on your iOS device under Accessibility > Motion > Reduce Motion

Use motion with purpose ensuring animations enhance the user experience rather than distract while always respecting user preferences by checking accessibility settings before applying them. When motion is reduced, offer static alternatives that still communicate the necessary information, and test your app to ensure it works smoothly with both standard and reduced motion settings.

0:00
/0:11