swift - Sprite Kit 的辅助功能(画外音)

标签 swift sprite-kit skspritenode uiaccessibility

我正在尝试在具有固定面板的益智游戏中添加对旁白辅助功能的支持。但是,我无法显示 UIAccessibilityElements

现在我正在我的 SKScene 中覆盖 accessibilityElementAtIndexaccessibilityElementCountindexOfAccessibilityElement

他们正在返回一个可访问元素数组:

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)
    }
}

其中 piece 是 SKSpriteNode 的子类并且定义了 getAccessibilityFrame:

func getAccessibilityFrame() -> CGRect
{
    return parentView!.convertRect(frame, toView: nil)
}

现在,一个(错误大小的)accessibility 元素似乎出现在屏幕上的错误位置。

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

非常感谢

编辑:
我尝试了一种 hack-ish 解决方法,将 UIView 放置在 SKView 上,UIButton 元素位于与 SKSpriteNodes 相同的位置。但是,可访问性仍然无法正常工作。 View 加载如下:

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)

}

按钮放置正确,但辅助功能根本不起作用。似乎有什么东西阻止它工作。

最佳答案

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

// Add the following code to a scene where you want to make the SKNode variable named “leave” an accessible button
// leave must already be initialized and added as a child of the scene, or a child of other SKNodes in the scene
// screenHeight must already be defined as the height of the device screen, in points

// Accessibility

private var accessibleElements: [UIAccessibilityElement] = []

private func nodeToDevicePointsFrame(node: SKNode) -> CGRect {

    // first convert from frame in SKNode to frame in SKScene's coordinates

    var sceneFrame = node.frame
    sceneFrame.origin = node.scene!.convertPoint(node.frame.origin, fromNode: node.parent!)

    // convert frame from SKScene coordinates to device points
    // sprite kit scene origin is in lower left, accessibility device screen origin is at upper left
    // assumes scene is initialized using SKSceneScaleMode.Fill using dimensions same as device points

    var deviceFrame = sceneFrame
    deviceFrame.origin.y = CGFloat(screenHeight-1) - (sceneFrame.origin.y + sceneFrame.size.height)
    return deviceFrame
}

private func initAccessibility() {
    if accessibleElements.count == 0 {
        let accessibleLeave = UIAccessibilityElement(accessibilityContainer: self.view!)
        accessibleLeave.accessibilityFrame = nodeToDevicePointsFrame(leave)
        accessibleLeave.accessibilityTraits = UIAccessibilityTraitButton
        accessibleLeave.accessibilityLabel = “leave” // the accessible name of the button
        accessibleElements.append(accessibleLeave)
    }
}
override func didMoveToView(view: SKView) {
    self.isAccessibilityElement = false
    leave.isAccessibilityElement = true
}

override func willMoveFromView(view: SKView) {
    accessibleElements = []
}

override func accessibilityElementCount() -> Int {
    initAccessibility()
    return accessibleElements.count
}

override func accessibilityElementAtIndex(index: Int) -> AnyObject? {
    initAccessibility()
    if (index < accessibleElements.count) {
        return accessibleElements[index] as AnyObject
    } else {
        return nil
    }
}

override func indexOfAccessibilityElement(element: AnyObject) -> Int {
    initAccessibility()
    return accessibleElements.indexOf(element as! UIAccessibilityElement)!
}

关于swift - Sprite Kit 的辅助功能(画外音),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30191912/

相关文章:

arrays - 使用 "+="运算符连接到可选数组

ios - 方向的 Swift 2 语法错误.Forward

ios - 如何调用另一个类中定义的函数?

ios - SKSpriteNode 隐藏在 UI 背景图像下

ios - SKAction 移动到 :duration: does not respond correctly on CGPoint value of the touch

ios - UICollectionview 重新排序单元格崩溃 ios swift

ios - View 未添加到 Xcode 中的顶 View Controller ?

swift - 如果选择了按钮,如何在按钮周围绘制圆圈?

ios - 离开 GameScene 时停止 SpriteKit 中的音乐

ios - SpriteKit 场景中的对象定位