[Hackathon 2024][Niobium][iOS] Respecting “Reduce Motion” Accessibility Settings in SwiftUI Animations
LaurentBnpp opened this issue · 0 comments
Rule title
Respecting “Reduce Motion” Accessibility Settings in SwiftUI Animations
Language and platform
Swift (5.3+), SwiftUI (iOS 13+, macOS 10.15+, tvOS 13+, watchOS 6+, visionOS 1+)
Rule description
This rule aims to ensure that developers write animations in SwiftUI while taking into account the user’s “Reduce Motion” accessibility settings. The “Reduce Motion” setting is an accessibility feature that minimizes the animations and transitions on the screen for users who are sensitive to motion.
Bad example
struct ContentView: View {
@State private var scale = 1.0
var body: some View {
VStack {
Spacer()
Circle()
.frame(width: 20, height: 20)
.scaleEffect(scale)
.animation( .spring(response: 1, dampingFraction: 0.1), value: scale)
Spacer()
Button("Increase Scale") {
scale *= 1.5
}
}
}
}
Good example
struct ContentView: View {
@Environment(\.accessibilityReduceMotion) var reduceMotion
@State private var scale = 1.0
var body: some View {
VStack {
Spacer()
Circle()
.frame(width: 20, height: 20)
.scaleEffect(scale)
.animation(reduceMotion ? nil : .spring(response: 1, dampingFraction: 0.1), value: scale)
Spacer()
Button("Increase Scale") {
scale *= 1.5
}
}
}
}
how-to-detect-the-reduce-motion-accessibility-setting-1.mp4
Rule short description
Ensure SwiftUI animations respect the user’s “Reduce Motion” accessibility setting.
Rule justification
Ignoring the “Reduce Motion” setting can lead to an uncomfortable user experience for those sensitive to motion and in the worst-case scenario, some users might no longer be able to use your application.
(https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#13.7)[RGAA Rule 13.7]
(https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#13.8)[RGAA Rule 13.8]
Severity / Remediation Cost
Severity: high.
Ignoring this setting can degrade the user experience, but it does not make the application unusable.
Remediation Cost: easy.
It only requires adding a condition to animations to respect the “Reduce Motion” setting.
Implementation principle
During the static analysis of the source code, we will need to detect instances where Animation is used without the @Environment(\.accessibilityReduceMotion) var reduceMotion modifier and animation(reduceMotion ? nil : .spring()).
Source video & code
Paul Hudson @twostraws December 1st 2022
https://www.hackingwithswift.com/quick-start/swiftui/how-to-detect-the-reduce-motion-accessibility-setting