2015-08-07 1 views
4

Je suis en train de faire mon MapView accessible, mais j'ai un isuue à le faire:Comment définir l'accessibilité uniquement aux annotations en mode carte?

Si je tente de rendre le Mapview accessible, en faisant ceci:

self.mapView.isAccessibilityElement=YES; 

Ensuite, l'affichage de la carte est pas lu par la voix plus.

Si je mets comme ceci:

self.mapView.isAccessibilityElement=NO; 

Puis la voix sur tout est à lire sur la carte, les rues, les bâtiments, mon emplacement actuel et mes annotations.

J'ai donné l'étiquette d'accessibilité et des conseils à mes annotations, mais je n'ai pas fourni d'autre valeur à mapview.

J'ai aussi essayé en définissant les éléments d'accessibilité dans la carte:

[self.mapView setAccessibilityElements:@[self.mapView.annotations,self.mapView.userLocation]]; 

Mais toujours pas de chance.

Existe-t-il de toute façon que la voix soit lue uniquement les annotations et néglige les éléments restants tels que les rues, les bâtiments?

Répondre

1

Je pense que vous rencontrez des difficultés car un MKMapView est un UIAccessibilityContainer, et donc isAccessibilityElement si false par défaut.

Vous devriez envisager de créer des rotors vocaux personnalisés qui permettent à l'utilisateur de naviguer dans votre application uniquement avec vos annotations.

Ceci est une bonne approche, car elle offre à l'utilisateur un moyen personnalisé de naviguer dans votre carte, tout en ne supprimant rien de l'accessibilité intégrée de MKMapView.

Il n'y a pratiquement pas d'exemples en ligne qui détaillent la création de rotors personnalisés, mais j'en ai créé un avec succès pour faire exactement ce que vous avez besoin de faire. J'ai suivi le WWDC Session 202 (commence à 24:17).

Voici mon code:

func configureCustomRotors() { 
    let favoritesRotor = UIAccessibilityCustomRotor(name: "Bridges") { predicate in 
    let forward = (predicate.searchDirection == .next) 

    // which element is currently highlighted 
    let currentAnnotationView = predicate.currentItem.targetElement as? MKPinAnnotationView 
    let currentAnnotation = (currentAnnotationView?.annotation as? BridgeAnnotation) 

    // easy reference to all possible annotations 
    let allAnnotations = self.mapView.annotations.filter { $0 is BridgeAnnotation } 

    // we'll start our index either 1 less or 1 more, so we enter at either 0 or last element 
    var currentIndex = forward ? -1 : allAnnotations.count 

    // set our index to currentAnnotation's index if we can find it in allAnnotations 
    if let currentAnnotation = currentAnnotation { 
     if let index = allAnnotations.index(where: { (annotation) -> Bool in 
     return (annotation.coordinate.latitude == currentAnnotation.coordinate.latitude) && 
    (annotation.coordinate.longitude == currentAnnotation.coordinate.longitude) 
     }) { 
      currentIndex = index 
     } 
    } 

    // now that we have our currentIndex, here's a helper to give us the next element 
    // the user is requesting 
    let nextIndex = {(index:Int) -> Int in forward ? index + 1 : index - 1} 

    currentIndex = nextIndex(currentIndex) 

    while currentIndex >= 0 && currentIndex < allAnnotations.count { 
     let requestedAnnotation = allAnnotations[currentIndex] 

     // i can't stress how important it is to have animated set to false. save yourself the 10 hours i burnt, and just go with it. if you set it to true, the map starts moving to the annotation, but there's no guarantee the annotation has an associated view yet, because it could still be animating. in which case the line below this one will be nil, and you'll have a whole bunch of annotations that can't be navigated to 
     self.mapView.setCenter(requestedAnnotation.coordinate, animated: false) 
     if let annotationView = self.mapView.view(for: requestedAnnotation) { 
     return UIAccessibilityCustomRotorItemResult(targetElement: annotationView, targetRange: nil) 
     } 

     currentIndex = nextIndex(currentIndex) 
    } 

    return nil 
    } 

    self.accessibilityCustomRotors = [favoritesRotor] 
}