Skip to content

Commit

Permalink
Improve navigation section
Browse files Browse the repository at this point in the history
  • Loading branch information
akaDuality committed Dec 24, 2023
1 parent a6b9d5f commit 0af83a7
Show file tree
Hide file tree
Showing 18 changed files with 184 additions and 56 deletions.
40 changes: 22 additions & 18 deletions Sources/AccessibilityDocumentation/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -306,24 +306,28 @@ extension UIAccessibilityTraits_ {
// public static var requiresActivation: UIAccessibility.DirectTouchOptions { get }
// }
//}
//extension UIAccessibility.Notification {
//
// public static var screenChanged: UIAccessibility.Notification
//
// public static var layoutChanged: UIAccessibility.Notification
//
// @available(iOS 4.0, *)
// public static var announcement: UIAccessibility.Notification
//
// @available(iOS 4.2, *)
// public static var pageScrolled: UIAccessibility.Notification
//
// @available(iOS 8.0, *)
// public static var pauseAssistiveTechnology: UIAccessibility.Notification
//
// @available(iOS 8.0, *)
// public static var resumeAssistiveTechnology: UIAccessibility.Notification
//}

extension Book {

/// Call this notification when entire screen had changed to rebuild accessibility tree. VoiceOver will notify by special signal. Modal and push presentation call this notification automatically.
public static var screenChanged: Notification = Notification(name: Notification.Name(rawValue: "screenChanged"))

/// Call this notification when part of a screen had changed to rebuild accessibility tree. Great for some disclosures area for e.g.
public static var layoutChanged: Notification = Notification(name: Notification.Name(rawValue: "screenChanged"))

/// Notify user when some process had completed. Examples: finish loading, complete order in restaurant
@available(iOS 4.0, *)
public static var announcement: Notification = Notification(name: Notification.Name(rawValue: "screenChanged"))

@available(iOS 4.2, *)
public static var pageScrolled: Notification = Notification(name: Notification.Name(rawValue: "screenChanged"))

@available(iOS 8.0, *)
public static var pauseAssistiveTechnology: Notification = Notification(name: Notification.Name(rawValue: "screenChanged"))

@available(iOS 8.0, *)
public static var resumeAssistiveTechnology: Notification = Notification(name: Notification.Name(rawValue: "screenChanged"))
}
//extension UIAccessibility.AssistiveTechnologyIdentifier {
//
// @available(iOS 8.0, *)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
# Switch Control

Allows to connect external devices and link them to any command. As a result paralyzed people can control a phone by simple signals: finger movement, muscle stretches, etc. Also, a iPhone's camera can recognize facial expression or any sound like a command. In the end user moves focus on screen and pass command to focused element by submenu that is presented after selection.
@Metadata {
@PageImage(
purpose: card,
source: "SwitchControlCover",
alt: "Switch Control with opened popover with actions: Select All, Deselect, Cut, Copy")
}


## Overview
Allows to connect external devices and link them to any command. As a result paralyzed people can control a phone by simple signals: finger movement, muscle stretches, etc. Also, a iPhone's camera can recognize facial expression or any sound like a command. In the end user moves focus on screen and pass command to focused element by submenu that is presented after selection.

![Switch control modes: focus groups on elements, cross selection and submenu](SwitchControlOverview)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
# Voice Control

Adds additional commands over graphical UI to control a phone by voice commands. A user of VoiceControl can see, but can't touch their phone, as a result he can pronounce commands lite "select Pepperoni", "tap purchase" or "close screen". iPhone recognizes speach, convert it to text and links command to elements' description.
Adds additional commands over graphical UI to control a phone by voice commands. A user of VoiceControl can see, but can't touch their phone, as a result he can pronounce commands lite "select Pepperoni", "tap purchase" or "close screen". iPhone recognizes speech, convert it to text and links command to elements' description.

@Metadata {
@PageImage(
purpose: card,
source: "Voice Control Cover",
alt: "Switch Control with opened popover with actions: Select All, Deselect, Cut, Copy")
}


## Overview
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

Helps blind or low-visioned persons to use a phone by listening audio description of UI and command by different swipes and non-direct touches. Developer prepare text description of the element, iPhone will generate voice description from text.

@Metadata {
@PageImage(
purpose: card,
source: "VoiceOver Cover",
alt: "Switch Control with opened popover with actions: Select All, Deselect, Cut, Copy")
}

## Overview

![VoiceOver gestures](VoiceOverGestures)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,21 @@ Visual hierarchy is based on child-parent relation and accessibility tree use th
// TODO: Container can has a label when use .semantic
}

### Focus order
``AccessibilityContainer/accessibilityElements``

@Comment {
// TODO: It should be part of <doc:ControlHierarchy>
}

#### Dynamic number of elements
https://github.com/akaDuality/RotorHeaders

### Tutorial

Read <doc:AdoptingCell> for example

### Modal views

Modal view should done three main things:
- Limit focus movement by himself. To mark a node as modal we use property ``Book/accessibilityViewIsModal``.
- Set focus to the first element by posting ``Book/post(notification:argument:)`` with type `.screenChanged`.
- Support escape gesture to close the screen by adding function ``Book/accessibilityPerformEscape`` to first responder

@Comment {
// TODO: Add link to notification
// TODO: Add Product Card tutorial
}

## Topics

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ Core properties that describes element for VoiceOver
To describe element we can use label, value and trait (like a type)

## Label

- ``Book/accessibilityLabel``
``Book/accessibilityLabel``

The main property is `accessibilityLabel` – defines element's name. It should be name in one or two words for buttons or represents full text from `UILabel`

Expand All @@ -21,8 +20,7 @@ The main property is `accessibilityLabel` – defines element's name. It should
> Tip: Voice Control can have synonims for label. Check ``Book/accessibilityUserInputLabels`` for more details.
## Value

- ``Book/accessibilityValue``
``Book/accessibilityValue``

`AccessibilityValue` is optional second part of the element's description. It can contain additional details or represents current value of the element
- *1.4 billions views* – no value for regular text is ofter situation
Expand All @@ -42,7 +40,7 @@ Important to understand differences between label and value. Label should be as
Otherwise, adjustable elements allow to change only value part and after change only value part will be pronounced to user. <doc:AdjustableElements>

## Trait
- ``Book/accessibilityTraits``
``Book/accessibilityTraits``

The last part of element's description is trait. Some traits may add additional text to element's description, other just changes behaviour.

Expand All @@ -57,21 +55,28 @@ The most common trait is ``UIAccessibilityTraits_/button`` – it helps user to
- *Pizza Pepperoni, Pepperoni, Mozzarella. **Button*** – tappable cell should contain button semantic, that's how user will understand that the cell is interactive and can be tapped.
- *Size, Medium. **Adjustable*** – VoiceOver can change inner value by vertical swipe.


@Image(source: "TraitsOrder", alt: "Reading order is controlled by designer")

> Note: Label and Value are separated by comma, but trait represents another sentence and separated by dot automatically.
> Important: Label and Value are `String` properties, but Trait can be selected only from limited amount of variants.
>
> Not duplicate trait's textual description inside Label or Value, because different technologies uses trait in different manear, not only for textual description.
### Tutorial
## Hint
``Book/accessibilityHint``

@Tutorial() {

Always disabled

@Comment {
// TODO: Describe hint
}

## Full formula
@Image(source: "TraitsOrder", alt: "Reading order is controlled by designer")

> Note: Container prefix is described in <doc:Navigation>
### Tutorial

Read <doc:AdoptingCell> for example

## Topics
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,88 @@
# Navigation

To simplify navigation developer had to achieve several goals: reduce number of elements, fix focus order and support several additional actions
To simplify navigation developer had to achieve several goals: call a notification to update accessibility tree, manage focus when a new screen is opened, support action for closing or completing the screen.

## Overview

<!--@START_MENU_TOKEN@-->Text<!--@END_MENU_TOKEN@-->

### Reduce number of elements
### Notifications

@Comment {
// TODO: It should be part of <doc:ControlHierarchy>
Notifications is mechanism to keep in sync current view hierarchy with accessibility tree. Every time when you update your UI you should call proper notification. Hopefully, some of them is called automatically.

@Links(visualStyle: list) {
- ``Book/announcement``
- ``Book/screenChanged``
- ``Book/layoutChanged``
- ``Book/pageScrolled``
- ``Book/pauseAssistiveTechnology``
- ``Book/resumeAssistiveTechnology``
}

### Focus order
### Modal view
``Book/accessibilityViewIsModal``

Set this property to any modal view to limit focus movement by this view.

Modal view should done three main things:
- Limit focus movement by himself. To mark a node as modal we use property ``Book/accessibilityViewIsModal``.
- Set focus to the first element by posting ``Book/post(notification:argument:)`` with type `.screenChanged` and set focus to first onscreen element.
- Support escape gesture to close the screen by adding function ``Book/accessibilityPerformEscape()`` to first responder

@Comment {
// TODO: Add link to notification
// TODO: Add Product Card tutorial
}

### Escape gesture

``Book/accessibilityPerformEscape()``

Escape gesture allows to close current screen by special gesture without focusing on "close" button.
- **For macOS app** it happened by *pressing "esc" button*,
- **For VoiceOver** you should swipe by *two finger up and down on screen several times like drawing N-symbol*.


@Comment {
// TODO: Add escape gesture video
// Do Switch control and voice control have support for this gesture? Can't find it for Switch Control
// TODO: Check https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/SupportingAccessibility.html
}

To handle escape gesture on your view you should override default implementation:

```
class ProductCardViewController: UIViewController {
override func accessibilityPerformEscape() -> Bool {
ingredientsCustomizationPopover.removeFromSuperView() // <- Call your type function
return true
}
}
```

> Note: Default modal and push navigation already supported escape gesture, but if you create your own custom navigation or modal screen you should implement escape function manually
### Magic tap

``Book/accessibilityPerformMagicTap()``

User can call "magic tap" gesture to perform main operation on the screen. Examples:
- Phone app: picks up or hangs up a call
- Clock app: start or stop a stopwatch
- Product card in food ordering app: add to cart
- Cart in food ordering app: create an order
- Taxi app: order a ride
- Focused textfield: start dictation

**VoiceOver** allows to *tap twice by two finger* in any place on the screen to perform magic tap
@Comment {
// TODO: how to call by switch control and voice control?
}

> Important: The action after magic tap gesture should be obvious to a user: absolutely nothing tell to user what action will be triggered. You can add hint to main button on screen that this button can be triggered by magic tap, but user offen distable hints, check <doc:DescribeElements> for more details
### Container

### Switch control and grouping

#### VoiceOver supports grouping
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,51 @@ To prototype interaction on early stage of development you can use [VoiceOver De

![Screenshot of the application](VoiceOverDesigner.png)

### Assistive Technologies
@Links(visualStyle: compactGrid) {
- <doc:VoiceOver>
- <doc:VoiceControl>
- <doc:SwitchControl>
}

## Tutorials


Step by step practice course.

- <doc:AdjustableTutorial>
- <doc:AdoptingCell>
@Links(visualStyle: detailedGrid) {
- <doc:AdjustableTutorial>
- <doc:AdoptingCell>
}

@Comment {

// TODO: Uncomment?

@TabNavigator {
@Tab("Switch Control") {
Allows to connect external devices and link them to any command. As a result paralyzed people can control a phone by simple signals: finger movement, muscle stretches, etc. Also, a iPhone's camera can recognize facial expression or any sound like a command. In the end user moves focus on screen and pass command to focused element by submenu that is presented after selection.
![Switch control modes: focus groups on elements, cross selection and submenu](SwitchControlOverview)
}


@Tab("Voice Control") {
Adds additional commands over graphical UI to control a phone by voice commands. A user of VoiceControl can see, but can't touch their phone, as a result he can pronounce commands lite "select Pepperoni", "tap purchase" or "close screen". iPhone recognizes speach, convert it to text and links command to elements' description.

![Voice Control modes: with labels, enumerated elements or grid](VoiceControlOverview)
}

@Tab("Voice Over") {
Helps blind or low-visioned persons to use a phone by listening audio description of UI and command by different swipes and non-direct touches. Developer prepare text description of the element, iPhone will generate voice description from text.

![VoiceOver gestures](VoiceOverGestures)
}
}
}


## Topics

### Assistive Technologies
- <doc:VoiceOver>
- <doc:VoiceControl>
- <doc:SwitchControl>

### Basic
- <doc:DescribeElements>
- <doc:ControlHierarchy>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,4 @@
}
}
}

}

6 changes: 6 additions & 0 deletions Sources/AccessibilityDocumentation/UIAccessibility_.swift
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,12 @@ public class Book {
@available(iOS 4.2, *)
open func accessibilityScroll(_ direction: UIAccessibilityScrollDirection) -> Bool { false }


/// Is called when user perform special closing gesture. VoiceOver calls this after drawing N-symbol by two finger.
///
/// See <doc:Navigation> for more details
///
/// - Returns: `true` if this class handles gestures. If `false` UIKit will traverse firstResponders for next element that can handle this gesture
@available(iOS 5.0, *)
open func accessibilityPerformEscape() -> Bool { false }

Expand Down

0 comments on commit 0af83a7

Please sign in to comment.