MKAnnotationView custom callout is invisible to Accessibility (VoiceOver)
Asked Answered
D

2

6

I have a MKAnnotationView subclass and place several of them on an MKMapView. The MKAnnotationView subclass sets some accessibility elements like this:

func applyAccessibility() {
    
    self.isAccessibilityElement = true
    self.accessibilityTraits = [.none]
    
    self.accessibilityLabel = "Bus stop map pin"
    self.accessibilityValue = busStop.name
}

VoiceOver reads out the names of the bus stops that are pinned on the map.

I then use a UIView subclass as the callout view when a bus stop is tapped.

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
    
    if let annotation = view.annotation
    {
        if annotation is MKUserLocation
        {
            // This is our location marker
            return
        }
        
        busStopAnnotationCalloutView.setupForAnnotationView(view, delegate: self)
        
        view.addSubview(busStopAnnotationCalloutView)
        
        mapView.setCenter(annotation.coordinate, animated: true)
    }
}

This works great, however this callout view is totally invisible to VoiceOver.

In the init of the callout view I set:

isAccessibilityElement = true
accessibilityTraits = .none
accessibilityLabel = "Callout view"
accessibilityIdentifier = "BusStopAnnotationCalloutView.callout"

and it also creates it's own labels and a button of which I set similar like this:

label.isAccessibilityElement = true
label.accessibilityTraits = .header
label.accessibilityLabel = "\(busStop.name)"

UIButton

button.isAccessibilityElement = true
button.accessibilityTraits = .button
button.accessibilityLabel = "Select this bus stop"

but none of these elements are visible to VoiceOver. The Accessibility Inspector can't see them.

As I move around the view with the Accessibility Inspector it just picks up and MKAnnotation's that are on the map underneath the callout.

EDIT --------

I have created a small example project that has a custom callout view that just won't get any accessibility.

Example project

And there's also a short screen recording showing the problem:

Video thumbnail
on YouTube

Divaricate answered 11/2, 2021 at 18:7 Comment(2)
I Can't download your example but I can reproduce the problem with my project. Did you try to use an UIAccessibilityContainer? #26538859 (Still on my todo list, sorry)Polydactyl
No, that question doesn't really explain it, but i'll do some research on that.Divaricate
O
4

The issue here is that your callout view is a child of your annotation view. Therefore if your annotation view has it's isAccessibilityElement set to true you can not focus on the callout. A way of solving this is setting the isAccessibilityElement of your annotation to false each time it is selected and vice versa.

Obstetric answered 30/11, 2021 at 12:46 Comment(1)
Wow! You are correct. Even Apple didn't pick up on this through both DTS and Bug Report. Thank you.Divaricate
D
0

After going directly to Apple with a Developer Technical Support request, they suggested it is a bug, however as this doesn't work on any version of iOS that I tested, i'd suggest it is more an oversight than a bug and i'm surprised no-one else has wanted to make a map view callout accessible.

Apple DTS also asked if I wanted them to look for a workaround and after a few days they came back to say there simply isn't one!

So for now, as of iOS 12.4, the answer here is that it's just not possible.

Divaricate answered 2/3, 2021 at 13:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.