How to set accessibility only for annotations in map view?

I am trying to make my access to the map, but I have isuue:

If I try to make mapView available by doing the following:

self.mapView.isAccessibilityElement=YES; 

Then the map display is not read by voice.

If I ask the following:

  self.mapView.isAccessibilityElement=NO; 

Then the voice reads everything on the map, streets, buildings, my current location and my annotations.

I gave an accessibility label and hints of my annotations, but I havent provided any other value for mapview.

I also tried setting accessibility elements to display the map:

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

But still no luck.

In any case, to read the voice, read only the annotations and ignore the remaining elements, such as streets, buildings?

+4
source share
1 answer

I think you are having difficulty because MKMapView is a UIAccessibilityContainer, and therefore isAccessibilityElement if false by default.

You should consider creating custom voice over rotors that allow the user to navigate your application only with your annotations.

This is a good approach because it provides the user with a customizable, user-friendly way to navigate your map, and also does not remove anything from MKMapView 's built-in accessibility.

There are hardly any examples on the Internet that detail the creation of custom rotors, but I just successfully created one that does exactly what you need for this. I followed WWDC Session 202 (starts at 24:17).

Here is my 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 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 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 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] } 
+1
source

All Articles