diff --git a/Sources/AccessibilityDocumentation/Documentation.docc/Articles/AssistiveTechnologies/SwitchControl.md b/Sources/AccessibilityDocumentation/Documentation.docc/Articles/AssistiveTechnologies/SwitchControl.md new file mode 100644 index 0000000..a57b7cb --- /dev/null +++ b/Sources/AccessibilityDocumentation/Documentation.docc/Articles/AssistiveTechnologies/SwitchControl.md @@ -0,0 +1,19 @@ +# SwitchControl + +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. + +## Overview + +![Switch control modes: focus groups on elements, cross selection and submenu](SwitchControlOverview) + +## How to setup + +## Command types + +## Single command + +## Importance of grouping + +## Face recognition + +## Sound Recognition diff --git a/Sources/AccessibilityDocumentation/Documentation.docc/Articles/AssistiveTechnologies/VoiceControl.md b/Sources/AccessibilityDocumentation/Documentation.docc/Articles/AssistiveTechnologies/VoiceControl.md new file mode 100644 index 0000000..4ef778e --- /dev/null +++ b/Sources/AccessibilityDocumentation/Documentation.docc/Articles/AssistiveTechnologies/VoiceControl.md @@ -0,0 +1,12 @@ +# VoiceControl + +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. + + + +## Overview + +![Voice Control modes: with labels, enumerated elements or grid](VoiceControlOverview) + + [Video how to use Voice Control](https://www.youtube.com/watch?v=eg22JaZWAgs) + diff --git a/Sources/AccessibilityDocumentation/Documentation.docc/Articles/AssistiveTechnologies/VoiceOver.md b/Sources/AccessibilityDocumentation/Documentation.docc/Articles/AssistiveTechnologies/VoiceOver.md new file mode 100644 index 0000000..b8bbc83 --- /dev/null +++ b/Sources/AccessibilityDocumentation/Documentation.docc/Articles/AssistiveTechnologies/VoiceOver.md @@ -0,0 +1,10 @@ +# VoiceOver + +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. + +## Overview + +![VoiceOver gestures](VoiceOverGestures) + + [Video how to navigate by VoiceOver](https://www.youtube.com/watch?v=qDm7GiKra28) + diff --git a/Sources/AccessibilityDocumentation/Documentation.docc/Articles/ControlHierarchy.md b/Sources/AccessibilityDocumentation/Documentation.docc/Articles/ControlHierarchy.md deleted file mode 100644 index 55df9fe..0000000 --- a/Sources/AccessibilityDocumentation/Documentation.docc/Articles/ControlHierarchy.md +++ /dev/null @@ -1,14 +0,0 @@ -# ControlHierarchy - -- ``Book/isAccessibilityElement`` -- ``Book/accessibilityElementsHidden`` -- ``Book/accessibilityViewIsModal`` -- ``Book/shouldGroupAccessibilityChildren`` - -## Overview - -Text - -### Section header - -Text diff --git a/Sources/AccessibilityDocumentation/Documentation.docc/Articles/Process/ControlHierarchy.md b/Sources/AccessibilityDocumentation/Documentation.docc/Articles/Process/ControlHierarchy.md new file mode 100644 index 0000000..6d7b19c --- /dev/null +++ b/Sources/AccessibilityDocumentation/Documentation.docc/Articles/Process/ControlHierarchy.md @@ -0,0 +1,49 @@ +# ControlHierarchy + +## Overview + +Assistive technologies take description of elements to provide different way of communications. The core part of this process is providing information about hierarchy of elements, what element should be focusable and what should be hidden from focus. + +### View hierarchy vs Accessibility Tree + +Regular screen we can describe like tree of Views with parent-child relation. Example: + +Screen with pizza: +``` +- Image +- Title +- Description container + - Size label + - Size segmented control wrapper + - Small size button + - Medium size button + - Large size button +- Purchase button + - Text inside button +``` + +VoiceOver needs another representation: +``` +- Title +- Size label +- Size segmented control as adjustable element +- Purchase button with text from the inside label +``` + +Voice Control and Switch Control place focus on buttons and tree should be different: +``` +- Small size button +- Medium size button +- Large size button +- Purchase button +``` + +As a result you can control what elements from your layout will be exposed to different technologies for better user experience. + +## Topics + +- ``Book/isAccessibilityElement`` +- ``Book/accessibilityElementsHidden`` +- ``Book/accessibilityViewIsModal`` +- ``Book/shouldGroupAccessibilityChildren`` +- ``AccessibilityContainer`` diff --git a/Sources/AccessibilityDocumentation/Documentation.docc/Articles/DescribeElements.md b/Sources/AccessibilityDocumentation/Documentation.docc/Articles/Process/DescribeElements.md similarity index 96% rename from Sources/AccessibilityDocumentation/Documentation.docc/Articles/DescribeElements.md rename to Sources/AccessibilityDocumentation/Documentation.docc/Articles/Process/DescribeElements.md index 97e7688..f9930ae 100644 --- a/Sources/AccessibilityDocumentation/Documentation.docc/Articles/DescribeElements.md +++ b/Sources/AccessibilityDocumentation/Documentation.docc/Articles/Process/DescribeElements.md @@ -37,7 +37,7 @@ The main property is `accessibilityLabel` – defines element's name. It should ### Label vs Value -Important to understand differences between label and value. Label should be as short as possible: Voice Control will use it as HUD over UI to name things for feature voice commantds, but not show value part, because we expect that it's already presented for user on screen. +Important to understand differences between label and value. Label should be as short as possible: Voice Control will use it as HUD over UI to name things for feature voice commands, but not show value part, because we expect that it's already presented for user on screen. Otherwise, adjustable elements allow to change only value part and after change only value part will be pronounced to user. diff --git a/Sources/AccessibilityDocumentation/Documentation.docc/Articles/Navigation.md b/Sources/AccessibilityDocumentation/Documentation.docc/Articles/Process/Navigation.md similarity index 100% rename from Sources/AccessibilityDocumentation/Documentation.docc/Articles/Navigation.md rename to Sources/AccessibilityDocumentation/Documentation.docc/Articles/Process/Navigation.md diff --git a/Sources/AccessibilityDocumentation/Documentation.docc/Articles/SpecificProperties.md b/Sources/AccessibilityDocumentation/Documentation.docc/Articles/Process/SpecificProperties.md similarity index 100% rename from Sources/AccessibilityDocumentation/Documentation.docc/Articles/SpecificProperties.md rename to Sources/AccessibilityDocumentation/Documentation.docc/Articles/Process/SpecificProperties.md diff --git a/Sources/AccessibilityDocumentation/Documentation.docc/Articles/VisualProperties.md b/Sources/AccessibilityDocumentation/Documentation.docc/Articles/Process/VisualProperties.md similarity index 100% rename from Sources/AccessibilityDocumentation/Documentation.docc/Articles/VisualProperties.md rename to Sources/AccessibilityDocumentation/Documentation.docc/Articles/Process/VisualProperties.md diff --git a/Sources/AccessibilityDocumentation/Documentation.docc/Documentation.md b/Sources/AccessibilityDocumentation/Documentation.docc/Documentation.md index 295b45f..48f7416 100644 --- a/Sources/AccessibilityDocumentation/Documentation.docc/Documentation.md +++ b/Sources/AccessibilityDocumentation/Documentation.docc/Documentation.md @@ -5,24 +5,20 @@ Accessibility part of UIKit and SwiftUI frameworks helps developers to represent ## Overview -- **VoiceOver** 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. - -[Video how to navigate by VoiceOver](https://www.youtube.com/watch?v=qDm7GiKra28) +- **** 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) -- **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 speach, convert it to text and links command to elements' description. -[Video how to use Voice Control](https://www.youtube.com/watch?v=eg22JaZWAgs) +![Voice Control modes: with labels, enumerated elements or grid](VoiceControlOverview) -![Voice C~ontrol modes: with labels, enumerated elements or grid](VoiceControlOverview) +- **** 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** 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) > Note: Watch [Apple's playlist about Accessibility ](https://www.youtube.com/playlist?list=PLIl2EzNYri0cLtSlZowttih25VnSvWITu) for inspiration -![Switch control modes: focus groups on elements, cross selection and submenu](SwitchControlOverview) - To prototype interaction on early stage of development you can use [VoiceOver Designer](https://rubanov.dev/voice-over-designer/) application for macOS. ![Screenshot of the application](VoiceOverDesigner.png) diff --git a/Sources/AccessibilityDocumentation/UIAccessibility+Container.swift b/Sources/AccessibilityDocumentation/UIAccessibility+Container.swift new file mode 100644 index 0000000..556769c --- /dev/null +++ b/Sources/AccessibilityDocumentation/UIAccessibility+Container.swift @@ -0,0 +1,94 @@ +import UIKit + +// +// UIAccessibilityContainer.h +// UIKit +// +// Copyright (c) 2016-2018 Apple Inc. All rights reserved. +// + +/** + UIAccessibilityContainer methods can be overridden to vend individual elements + that are managed by a single UIView. + + For example, a single UIView might draw several items that (to an + end user) have separate meaning and functionality. It is important to vend + each item as an individual accessibility element. + + Sub-elements of a container that are not represented by concrete UIView + instances (perhaps painted text or icons) can be represented using instances + of UIAccessibilityElement class (see UIAccessibilityElement.h). + + Accessibility containers MUST return NO to -isAccessibilityElement. + */ +public class AccessibilityContainer { + + + @MainActor open func accessibilityElementCount() -> Int { 0 } + + + @MainActor open func accessibilityElement(at index: Int) -> Any? { nil } + + + @MainActor open func index(ofAccessibilityElement element: Any) -> Int { 0 } + + + /// A list of container elements managed by the receiver. + /// This can be used as an alternative to implementing the dynamic methods. + /// default == nil + @available(iOS 8.0, *) + @MainActor open var accessibilityElements: [Any]? = nil + + + /// Some containers provide more context for accessibility elements, such as tables or lists. + /// Set this property so that assistive technologies can output more information. + /// default == UIAccessibilityContainerTypeNone + @available(iOS 11.0, *) + @MainActor open var accessibilityContainerType: UIAccessibilityContainerType = .none + + + /// An array of container elements similar to accessibilityElements but specific for automation. + /// This can be used to modify the children in the accessibility tree for automation. + /// If not set, automationElements will default first to accessibilityElements if it’s not an accessibility element. + /// If there are no accessibilityElements and the view is an accessibility element, it will return the list of subviews that have accessibilityIdentifier. + /// Otherwise, the default will be an empty array. + @available(iOS 17.0, *) + @MainActor open var automationElements: [Any]? = nil +} + +/** + The UIAccessibilityContainerDataTable and UIAccessibilityContainerDataTableCell protocols + convey more information specific to tables that contain structured data. + */ + +@available(iOS 11.0, *) +@MainActor public protocol UIAccessibilityContainerDataTableCell : NSObjectProtocol { + + + /// The row/column index + the row/column span. + /// default == { NSNotFound, 0 } + func accessibilityRowRange() -> NSRange + + func accessibilityColumnRange() -> NSRange +} + +@available(iOS 11.0, *) +@MainActor public protocol UIAccessibilityContainerDataTable : NSObjectProtocol { + + + /// Return the cell element for a specific row/column, including elements that span rows/columns. + /// default == nil + func accessibilityDataTableCellElement(forRow row: Int, column: Int) -> UIAccessibilityContainerDataTableCell? + + + func accessibilityRowCount() -> Int + + func accessibilityColumnCount() -> Int + + + /// Return header elements for a specific row or column. + /// default == nil + func accessibilityHeaderElements(forRow row: Int) -> [UIAccessibilityContainerDataTableCell]? + + func accessibilityHeaderElements(forColumn column: Int) -> [UIAccessibilityContainerDataTableCell]? +} diff --git a/Sources/AccessibilityDocumentation/UIAccessibility_.swift b/Sources/AccessibilityDocumentation/UIAccessibility_.swift index 2616e69..d084053 100644 --- a/Sources/AccessibilityDocumentation/UIAccessibility_.swift +++ b/Sources/AccessibilityDocumentation/UIAccessibility_.swift @@ -23,9 +23,12 @@ public class Book { /** Return YES if the receiver should be exposed as an accessibility element. + + Setting the property to YES will cause the receiver to be visible to assistive applications: VoiceOver will focus on this element to speak aloud it, Voice control and Switch Control will focus is elements it intrectitve + default == NO default on UIKit controls == YES - Setting the property to YES will cause the receiver to be visible to assistive applications. + */ open var isAccessibilityElement: Bool = false @@ -157,6 +160,7 @@ public class Book { /** Marks all the accessible elements contained within as hidden. + default == NO */ @available(iOS 5.0, *) @@ -166,6 +170,9 @@ public class Book { /** Informs whether the receiving view should be considered modal by accessibility. If YES, then elements outside this view will be ignored. Only elements inside this view will be exposed. + + > Tip: Support action to close modal view with special gesture. + default == NO */ @available(iOS 5.0, *) @@ -173,10 +180,12 @@ public class Book { /** - Forces children elements to be grouped together regardless of their position on screen. + Forces children elements to be grouped together regardless of their position on screen. Move focus to nearest element, not to the next by reading order. + For example, your app may show items that are meant to be grouped together in vertical columns. By default, VoiceOver will navigate those items in horizontal rows. If shouldGroupAccessibilityChildren is set on a parent view of the items in the vertical column, VoiceOver will navigate the order correctly. + default == NO */ @available(iOS 6.0, *)