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.
And there's also a short screen recording showing the problem:
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.