The basic idea is to create accessibility material for the elements you want to test in the user interface. It means:
List of all available items contained in the scene.
Set options for each of these elements, especially the data frame .
Step by step
This answer is for Swift 3 and is mainly based on Availability (voice) using the Sprite Kit
Let's say I want to make a SpriteKit button called tapMe .
List of available items.
Add an array of UIAccessibilityElement to the scene.
var accessibleElements: [UIAccessibilityElement] = []
Scene life cycle
I need to update two methods: didMove(to:) and willMove(from:) .
override func didMove(to view: SKView) { isAccessibilityElement = false tapMe.isAccessibilityElement = true }
Since the scene is an availability controller, in the declared documentation, it should return False in isAccessibilityElement .
and
override func willMove(from view: SKView) { accessibleElements.removeAll() }
Override UIAccessibilityContainer Methods
3 methods: accessibilityElementCount() , accessibilityElement(at index:) and index(ofAccessibilityElement . Let me introduce the initAccessibility() method, which I will describe below.
override func accessibilityElementCount() -> Int { initAccessibility() return accessibleElements.count } override func accessibilityElement(at index: Int) -> Any? { initAccessibility() if (index < accessibleElements.count) { return accessibleElements[index] } else { return nil } } override func index(ofAccessibilityElement element: Any) -> Int { initAccessibility() return accessibleElements.index(of: element as! UIAccessibilityElement)! }
Initialize accessibility for the scene
func initAccessibility() { if accessibleElements.count == 0 { // 1. let elementForTapMe = UIAccessibilityElement(accessibilityContainer: self.view!) // 2. var frameForTapMe = tapMe.frame // From Scene to View frameForTapMe.origin = (view?.convert(frameForTapMe.origin, from: self))! // Don't forget origins are different for SpriteKit and UIKit: // - SpriteKit is bottom/left // - UIKit is top/left // y // ┌────┐ ▲ // │ │ │ x // ◉────┘ └──▶ // // x // ◉────┐ ┌──▶ // │ │ │ // └────┘ y ▼ // // Thus before the following conversion, origin value indicate the bottom/left edge of the frame. // We then need to move it to top/left by retrieving the height of the frame. // frameForTapMe.origin.y = frameForTapMe.origin.y - frameForTapMe.size.height // 3. elementForTapMe.accessibilityLabel = "tap Me" elementForTapMe.accessibilityFrame = frameForTapMe elementForTapMe.accessibilityTraits = UIAccessibilityTraitButton // 4. accessibleElements.append(elementForTapMe) } }
- Create
UIAccessibilityElement for tapMe - Calculate frame data in device coordinates. Do not forget that the beginning of the
frame is the top / left corner for UIKit - Set data for
UIAccessibilityElement - Add this
UIAccessibilityElement list of all available items in the scene.
tapMe is now available in terms of user interface testing.
References
source share