使用Sprite Kit的辅助功能(配音)

Mas*_*son 5 uiaccessibility sprite-kit skspritenode swift

我试图在具有固定板的益智游戏中添加对Voice Over accessibility的支持.但是,我很难UIAccessibilityElements出现.

现在我重写accessibilityElementAtIndex,accessibilityElementCountindexOfAccessibilityElement在我的SKScene.

他们返回一组可访问的元素:

func loadAccessibleElements()
{
    self.isAccessibilityElement = false

    let pieces = getAllPieces()

    accessibleElements.removeAll(keepCapacity: false)
    for piece in pieces
    {
        let element = UIAccessibilityElement(accessibilityContainer: self.usableView!)

        element.accessibilityFrame = piece.getAccessibilityFrame()
        element.accessibilityLabel = piece.getText()
        element.accessibilityTraits = UIAccessibilityTraitButton
        accessibleElements.append(element)
    }
}
Run Code Online (Sandbox Code Playgroud)

其中piece是子类,SKSpriteNodegetAccessibilityFrame定义为:

func getAccessibilityFrame() -> CGRect
{
    return parentView!.convertRect(frame, toView: nil)
}
Run Code Online (Sandbox Code Playgroud)

现在,一个(尺寸错误的)accessibility元素似乎出现在错误的地方.

有人能指出我正确的方向吗?

非常感谢

编辑:
我已经尝试了一个hack-ish工作,将UIView放在SKView上,UIButton元素放在与SKSpriteNodes相同的位置.但是,可访问性仍然不希望工作.视图按如下方式加载:

func loadAccessibilityView()
{
    view.isAccessibilityElement = false
    view.accessibilityElementsHidden = false
    skView.accessibilityElementsHidden = false
    let accessibleSubview = UIView(frame: view.frame)
    accessibleSubview.userInteractionEnabled = true
    accessibleSubview.isAccessibilityElement = false
    view.addSubview(accessibleSubview)
    view.bringSubviewToFront(accessibleSubview)

    let pieces = (skView.scene! as! GameScene).getAllPieces()
    for piece in pieces
    {
        let pieceButton = UIButton(frame: piece.getAccessibilityFrame())
        pieceButton.isAccessibilityElement = true
        pieceButton.accessibilityElementsHidden = false
        pieceButton.accessibilityTraits = UIAccessibilityTraitButton
        pieceButton.setTitle(piece.getText(), forState: UIControlState.Normal)
        pieceButton.setBackgroundImage(UIImage(named: "blue-button"), forState: UIControlState.Normal)
        pieceButton.alpha = 0.2
        pieceButton.accessibilityLabel = piece.getText()
        pieceButton.accessibilityFrame = pieceButton.frame
        pieceButton.addTarget(self, action: Selector("didTap:"), forControlEvents: UIControlEvents.TouchUpInside)
        accessibleSubview.addSubview(pieceButton)
    }

    UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil)

}
Run Code Online (Sandbox Code Playgroud)

按钮放置正确,但可访问性根本无法正常工作.似乎有些东西阻止它起作用.

小智 2

我徒劳地搜索了如何使用 SpriteKit 在 Swift 中实现 VoiceOver 的描述,所以我终于弄清楚了如何做到这一点。下面是一些工作代码,当添加到 SKScene 类时,它将 SKNode 转换为可访问的按钮:

\n\n
// Add the following code to a scene where you want to make the SKNode variable named \xe2\x80\x9cleave\xe2\x80\x9d an accessible button\n// leave must already be initialized and added as a child of the scene, or a child of other SKNodes in the scene\n// screenHeight must already be defined as the height of the device screen, in points\n\n// Accessibility\n\nprivate var accessibleElements: [UIAccessibilityElement] = []\n\nprivate func nodeToDevicePointsFrame(node: SKNode) -> CGRect {\n\n    // first convert from frame in SKNode to frame in SKScene's coordinates\n\n    var sceneFrame = node.frame\n    sceneFrame.origin = node.scene!.convertPoint(node.frame.origin, fromNode: node.parent!)\n\n    // convert frame from SKScene coordinates to device points\n    // sprite kit scene origin is in lower left, accessibility device screen origin is at upper left\n    // assumes scene is initialized using SKSceneScaleMode.Fill using dimensions same as device points\n\n    var deviceFrame = sceneFrame\n    deviceFrame.origin.y = CGFloat(screenHeight-1) - (sceneFrame.origin.y + sceneFrame.size.height)\n    return deviceFrame\n}\n\nprivate func initAccessibility() {\n    if accessibleElements.count == 0 {\n        let accessibleLeave = UIAccessibilityElement(accessibilityContainer: self.view!)\n        accessibleLeave.accessibilityFrame = nodeToDevicePointsFrame(leave)\n        accessibleLeave.accessibilityTraits = UIAccessibilityTraitButton\n        accessibleLeave.accessibilityLabel = \xe2\x80\x9cleave\xe2\x80\x9d // the accessible name of the button\n        accessibleElements.append(accessibleLeave)\n    }\n}\noverride func didMoveToView(view: SKView) {\n    self.isAccessibilityElement = false\n    leave.isAccessibilityElement = true\n}\n\noverride func willMoveFromView(view: SKView) {\n    accessibleElements = []\n}\n\noverride func accessibilityElementCount() -> Int {\n    initAccessibility()\n    return accessibleElements.count\n}\n\noverride func accessibilityElementAtIndex(index: Int) -> AnyObject? {\n    initAccessibility()\n    if (index < accessibleElements.count) {\n        return accessibleElements[index] as AnyObject\n    } else {\n        return nil\n    }\n}\n\noverride func indexOfAccessibilityElement(element: AnyObject) -> Int {\n    initAccessibility()\n    return accessibleElements.indexOf(element as! UIAccessibilityElement)!\n}\n
Run Code Online (Sandbox Code Playgroud)\n