System Gesture Safe Zone
Status: ready
Intent
Drag interactions stay away from the screen edges the system uses. A control that has to be near an edge also has a way to use it without dragging.
Problem
A date scroller, a media scrubber or a sheet handle sits at the bottom edge. A horizontal drag switches apps, an upward drag goes Home, a downward drag triggers Reachability. Touch users hit it occasionally. Users with a tremor or using one hand hit it constantly. Switch Control can't drag at all.
Solution
Verdict: the bottom edge is shared with the system. Drag controls go above the safe area, and each one has buttons or a list next to it.
Why: distance from the edge cuts accidental system gestures for touch users. Buttons remove the drag for everyone else. Safe area padding alone does only the first.
Review shortcut for the bottom edge:
Fine: a primary button with a 44 pt hit area
a system tab bar
passive content
Avoid: a horizontal scroller
drag to confirm
swipe to dismiss as the only exit
a scrubber without step buttons
Implementation
A date scroller:
HStack {
Button("Previous day", systemImage: "chevron.left") { day = day.previous }
DateScroller(selection: $day)
Button("Next day", systemImage: "chevron.right") { day = day.next }
}
.labelStyle(.iconOnly)
.safeAreaPadding(.bottom)
The drag stays as a shortcut. The task doesn't depend on it.
A sheet handle isn't the only way to expand or close:
VStack {
Capsule().frame(width: 36, height: 5)
.accessibilityHidden(true)
Button("Show details") { expand() }
Button("Close") { close() }
}
Native .sheet with .presentationDetents already gives VoiceOver an adjustable handle and a close path. Custom sheets need the buttons.
Check
Profile: touch, one hand, Reachability on
Task: choose a day 3 days ahead
Expected: no Reachability, no app switch, no Home
Profile: VoiceOver
Task: choose the next day
Expected: the selected day says "Selected"
Next day is reachable, no drag needed
Profile: Larger Text AX3
Task: use the bottom controls
Expected: controls stay above the Home indicator, text isn't clipped
Pitfalls
- "Fixing" the conflict with
.defersSystemGestures. It makes the user swipe twice to go Home. - All controls behind a sheet handle.
- A haptic as the only sign that the drag worked.
- Assuming safe area padding makes a drag accessible.
WCAG mapping
2.5.1 Pointer Gestures: path gestures have an alternative.2.5.7 Dragging Movements: a drag has an alternative.2.5.8 Target Size (Minimum): edge controls are large enough.