added rotor
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
0777898e8a
commit
ab16fb4642
@ -48,6 +48,7 @@
|
|||||||
EA3C3BB528996775000CA526 /* StoryboardInitable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3C3BB128996775000CA526 /* StoryboardInitable.swift */; };
|
EA3C3BB528996775000CA526 /* StoryboardInitable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3C3BB128996775000CA526 /* StoryboardInitable.swift */; };
|
||||||
EA3C3BB628996775000CA526 /* MenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3C3BB228996775000CA526 /* MenuViewController.swift */; };
|
EA3C3BB628996775000CA526 /* MenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3C3BB228996775000CA526 /* MenuViewController.swift */; };
|
||||||
EA3C3BB728996775000CA526 /* ToggleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3C3BB328996775000CA526 /* ToggleViewController.swift */; };
|
EA3C3BB728996775000CA526 /* ToggleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3C3BB328996775000CA526 /* ToggleViewController.swift */; };
|
||||||
|
EA471F402A97BEAA00CE9E58 /* CustomRotorable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA471F3F2A97BEAA00CE9E58 /* CustomRotorable.swift */; };
|
||||||
EA4DB30428DCD25B00103EE3 /* BadgeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4DB30328DCD25B00103EE3 /* BadgeViewController.swift */; };
|
EA4DB30428DCD25B00103EE3 /* BadgeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4DB30328DCD25B00103EE3 /* BadgeViewController.swift */; };
|
||||||
EA596ABA2A16B2ED00300C4B /* TabsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA596AB92A16B2ED00300C4B /* TabsViewController.swift */; };
|
EA596ABA2A16B2ED00300C4B /* TabsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA596AB92A16B2ED00300C4B /* TabsViewController.swift */; };
|
||||||
EA5E3050294D11540082B959 /* TileContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5E304F294D11540082B959 /* TileContainerViewController.swift */; };
|
EA5E3050294D11540082B959 /* TileContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5E304F294D11540082B959 /* TileContainerViewController.swift */; };
|
||||||
@ -144,6 +145,7 @@
|
|||||||
EA3C3BB128996775000CA526 /* StoryboardInitable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryboardInitable.swift; sourceTree = "<group>"; };
|
EA3C3BB128996775000CA526 /* StoryboardInitable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryboardInitable.swift; sourceTree = "<group>"; };
|
||||||
EA3C3BB228996775000CA526 /* MenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuViewController.swift; sourceTree = "<group>"; };
|
EA3C3BB228996775000CA526 /* MenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuViewController.swift; sourceTree = "<group>"; };
|
||||||
EA3C3BB328996775000CA526 /* ToggleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ToggleViewController.swift; sourceTree = "<group>"; };
|
EA3C3BB328996775000CA526 /* ToggleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ToggleViewController.swift; sourceTree = "<group>"; };
|
||||||
|
EA471F3F2A97BEAA00CE9E58 /* CustomRotorable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomRotorable.swift; sourceTree = "<group>"; };
|
||||||
EA4DB30328DCD25B00103EE3 /* BadgeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeViewController.swift; sourceTree = "<group>"; };
|
EA4DB30328DCD25B00103EE3 /* BadgeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeViewController.swift; sourceTree = "<group>"; };
|
||||||
EA596AB92A16B2ED00300C4B /* TabsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsViewController.swift; sourceTree = "<group>"; };
|
EA596AB92A16B2ED00300C4B /* TabsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsViewController.swift; sourceTree = "<group>"; };
|
||||||
EA5E304F294D11540082B959 /* TileContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileContainerViewController.swift; sourceTree = "<group>"; };
|
EA5E304F294D11540082B959 /* TileContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileContainerViewController.swift; sourceTree = "<group>"; };
|
||||||
@ -294,6 +296,7 @@
|
|||||||
EAF7F07E28996A0700B287F5 /* Protocols */ = {
|
EAF7F07E28996A0700B287F5 /* Protocols */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
EA471F3F2A97BEAA00CE9E58 /* CustomRotorable.swift */,
|
||||||
EA3C3BB028996775000CA526 /* PickerBase.swift */,
|
EA3C3BB028996775000CA526 /* PickerBase.swift */,
|
||||||
EA3C3BB128996775000CA526 /* StoryboardInitable.swift */,
|
EA3C3BB128996775000CA526 /* StoryboardInitable.swift */,
|
||||||
);
|
);
|
||||||
@ -498,6 +501,7 @@
|
|||||||
445BA07A29C088470036A7C5 /* NotificationViewController.swift in Sources */,
|
445BA07A29C088470036A7C5 /* NotificationViewController.swift in Sources */,
|
||||||
EAF7F11A28A14A0E00B287F5 /* RadioButtonGroupViewController.swift in Sources */,
|
EAF7F11A28A14A0E00B287F5 /* RadioButtonGroupViewController.swift in Sources */,
|
||||||
EA89204628B66CE2006B9984 /* ScrollViewController.swift in Sources */,
|
EA89204628B66CE2006B9984 /* ScrollViewController.swift in Sources */,
|
||||||
|
EA471F402A97BEAA00CE9E58 /* CustomRotorable.swift in Sources */,
|
||||||
EA3C3B9F289966EF000CA526 /* SceneDelegate.swift in Sources */,
|
EA3C3B9F289966EF000CA526 /* SceneDelegate.swift in Sources */,
|
||||||
EA0D1C332A673FD400E5C127 /* RadioButtonItemViewController.swift in Sources */,
|
EA0D1C332A673FD400E5C127 /* RadioButtonItemViewController.swift in Sources */,
|
||||||
5FC35BE928D5235A004EBEAC /* ButtonViewController.swift in Sources */,
|
5FC35BE928D5235A004EBEAC /* ButtonViewController.swift in Sources */,
|
||||||
|
|||||||
107
VDSSample/Protocols/CustomRotorable.swift
Normal file
107
VDSSample/Protocols/CustomRotorable.swift
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
//
|
||||||
|
// AccessibilityCustomRotorable.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 8/24/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
public protocol CustomRotorable: UIViewController {
|
||||||
|
var customRotorCache: [String: [UIView]] { get set }
|
||||||
|
var customRotors: [CustomRotorType] { get set }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension CustomRotorable {
|
||||||
|
|
||||||
|
/// Adds CustomRotor to the accessibilityCustomRotors array.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - name: Name that will show up in the Rotor picker.
|
||||||
|
/// - trait: Any UIView that has this traits will be added to this Name.
|
||||||
|
internal func addCustomRotor(with name: String, for trait: UIAccessibilityTraits) {
|
||||||
|
//filter out old rotors with same name
|
||||||
|
accessibilityCustomRotors = (accessibilityCustomRotors ?? []).filter { $0.name != name }
|
||||||
|
|
||||||
|
//create new rotor
|
||||||
|
let newRotor = UIAccessibilityCustomRotor(name: name) { [weak self] predicate in
|
||||||
|
guard let self else { return nil }
|
||||||
|
|
||||||
|
//create the view accessibleElements cache if it doesn't exist
|
||||||
|
if self.customRotorCache[name] == nil {
|
||||||
|
self.customRotorCache[name] = self.view.accessibleElements(with: trait)
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let views = self.customRotorCache[name], !views.isEmpty else { return nil }
|
||||||
|
|
||||||
|
let currentIndex = views.firstIndex(where: { $0 === predicate.currentItem.targetElement })
|
||||||
|
let count = views.count
|
||||||
|
|
||||||
|
//find the nextIndex
|
||||||
|
let nextIndex: Int
|
||||||
|
switch predicate.searchDirection {
|
||||||
|
case .next:
|
||||||
|
if let currentIndex, currentIndex != count - 1{
|
||||||
|
//go forwards
|
||||||
|
nextIndex = currentIndex + 1
|
||||||
|
} else {
|
||||||
|
//get the first
|
||||||
|
nextIndex = 0
|
||||||
|
}
|
||||||
|
case .previous:
|
||||||
|
if let currentIndex, currentIndex != 0 {
|
||||||
|
//go backwards
|
||||||
|
nextIndex = currentIndex - 1
|
||||||
|
} else {
|
||||||
|
//get the last
|
||||||
|
nextIndex = count - 1
|
||||||
|
}
|
||||||
|
@unknown default:
|
||||||
|
//get the first
|
||||||
|
nextIndex = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return UIAccessibilityCustomRotorItemResult(targetElement: views[nextIndex], targetRange: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
//append rotor
|
||||||
|
accessibilityCustomRotors?.append(newRotor)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Loads all of the custom rotors for the screen.
|
||||||
|
public func loadCustomRotors() {
|
||||||
|
customRotorCache.removeAll()
|
||||||
|
UIAccessibility.post(notification: .screenChanged, argument: nil)
|
||||||
|
customRotors.forEach { addCustomRotor(with: $0.name, for: $0.trait) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension UIView {
|
||||||
|
|
||||||
|
/// Gets all of the Views that has the matching accessibilityTrait.
|
||||||
|
/// - Parameter trait: This is the trailt for the accessibilityTrait property of a view.
|
||||||
|
/// - Returns: An array of RotorItemResult
|
||||||
|
func accessibleElements(with trait: UIAccessibilityTraits) -> [UIView] {
|
||||||
|
var elements: [UIView] = []
|
||||||
|
|
||||||
|
//add your self if you meet the requirements
|
||||||
|
if isAccessibilityElement, accessibilityTraits.contains(trait) {
|
||||||
|
elements.append(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
//loop through your subviews
|
||||||
|
subviews.forEach { elements.append(contentsOf: $0.accessibleElements(with: trait)) }
|
||||||
|
|
||||||
|
return elements
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct CustomRotorType {
|
||||||
|
public var name: String
|
||||||
|
public var trait: UIAccessibilityTraits
|
||||||
|
|
||||||
|
public init(name: String, trait: UIAccessibilityTraits) {
|
||||||
|
self.name = name
|
||||||
|
self.trait = trait
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user