2015-05-12 10 views
5

Sto tentando di aggiungere il supporto per l'accessibilità Voice Over in un puzzle game che ha una scheda fissa. Tuttavia, ho difficoltà a visualizzare UIAccessibilityElements.Accessibilità (Voice Over) con il kit Sprite

In questo momento sto ignorando accessibilityElementAtIndex, accessibilityElementCount e indexOfAccessibilityElement nel mio SKScene.

Sono restituendo un array di elementi accessibili come tale:

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

Dove pezzo è una sottoclasse di SKSpriteNode e getAccessibilityFrame è definito:

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

momento uno (erroneamente dimensioni) accessibility elemento sembra apparire sullo schermo nel posto sbagliato.

Qualcuno potrebbe indicarmi la giusta direzione?

Molte grazie

EDIT:
Ho provato un lavoro hack-ish intorno ponendo un UIView sopra la SKView con elementi UIButton nella stessa posizione del SKSpriteNodes. Tuttavia, l'accessibilità non vuole ancora funzionare. La vista viene caricata come tale:

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) 

} 

I pulsanti sono posizionati correttamente, tuttavia l'accessibilità non funziona affatto. Qualcosa sembra impedirgli di funzionare.

+0

Oltre a questo, ho cercato un altro modo - ho aggiunto una visualizzazione secondaria di UIButtons in sovrapposizione stessa posizione esatta come skspritenodes . Sono rimasto sorpreso dal fatto che anche questi pulsanti non possano essere ascoltati da Voice Over. Ho fatto un errore bloccando gli input? Lo skscene stesso sovrascrive touchBegun (...) ecc. – Mason

risposta

2

Ho cercato invano una descrizione di come implementare VoiceOver in Swift utilizzando SpriteKit, così ho finalmente capito come farlo. Ecco qualche codice di lavoro che converte uno SKNode ad un pulsante accessibile quando aggiunta ad una classe SKScene:

// 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)! 
} 
0

I telegrammi di accessibilità sono definiti nelle coordinate fisiche dello schermo , non in UIView e la trasformazione tra di essi è un po 'complicata.

L'origine del dispositivo è in basso a sinistra sullo schermo, con X su, quando il dispositivo è in modalità orizzontale.

È una conversione del dolore, non ho idea del motivo per cui Apple ha fatto così.

+0

Sì, sono una seccatura, ho provato alcune varianti sulla funzione getAccessibilityFrame, che non funzionavano correttamente. Sono riuscito a ottenere gli UIButtons sovrapposti sugli elementi sprite, ma l'accessibilità non funziona nemmeno per loro. Mi sento come se la SKScene stia confondendo gli input? Toccando e trascinandolo fa solo un rumore come se avessi provato a selezionare un'area vuota senza accessibilità. Mi dilungherò nella mia domanda al più presto – Mason

+0

Sono stato fortunato nel ritenere che le specifiche dell'app vadano solo a sinistra e a destra, quindi è stato facile gestire la trasformazione quando non funzionavano in modo coerente. –

+0

L'elemento di accessibilità è solo un'area di messa a fuoco per un tocco o un gesto, quindi tutto ciò che blocca lo manterrebbe effettivamente dal suo funzionamento. Sei sicuro che il tuo contenitore di accessibilità, se ne hai uno, restituisca "no"? –

Problemi correlati