From c349d8f561820e44cd1fe2686f317e99c99df0c0 Mon Sep 17 00:00:00 2001 From: Alan Chu Date: Sun, 19 Sep 2021 11:21:45 -0700 Subject: [PATCH] Skip map annotation callout when voiceover is enabled Fixes #526 --- OBAKit/Mapping/MapViewController.swift | 9 +++++++-- OBAKit/Mapping/StopAnnotationView.swift | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/OBAKit/Mapping/MapViewController.swift b/OBAKit/Mapping/MapViewController.swift index cff78d6c9..26933f608 100644 --- a/OBAKit/Mapping/MapViewController.swift +++ b/OBAKit/Mapping/MapViewController.swift @@ -454,6 +454,12 @@ public class MapViewController: UIViewController, present(alert, animated: true) { mapView.deselectAnnotation(view.annotation, animated: true) } + } else if let stop = view.annotation as? Stop, UIAccessibility.isVoiceOverRunning { + // When VoiceOver is running, StopAnnotationView does not display a callout due to + // VoiceOver limitations with MKMapView. Therefore, we should skip any callouts + // and just go directly to pushing the stop onto the navigation stack. + application.analytics?.reportEvent?(.userAction, label: AnalyticsLabels.mapStopAnnotationTapped, value: nil) + show(stop: stop) } } @@ -472,8 +478,7 @@ public class MapViewController: UIViewController, if let stop = view.annotation as? Stop { application.analytics?.reportEvent?(.userAction, label: AnalyticsLabels.mapStopAnnotationTapped, value: nil) show(stop: stop) - } - else if let bookmark = view.annotation as? Bookmark { + } else if let bookmark = view.annotation as? Bookmark { application.analytics?.reportEvent?(.userAction, label: AnalyticsLabels.mapStopAnnotationTapped, value: nil) show(stop: bookmark.stop) } diff --git a/OBAKit/Mapping/StopAnnotationView.swift b/OBAKit/Mapping/StopAnnotationView.swift index 881539a32..072aa12bb 100644 --- a/OBAKit/Mapping/StopAnnotationView.swift +++ b/OBAKit/Mapping/StopAnnotationView.swift @@ -73,7 +73,9 @@ class StopAnnotationView: MKAnnotationView { rightCalloutAccessoryView = UIButton.chevronButton annotationSize = ThemeMetrics.defaultMapAnnotationSize - canShowCallout = true + updateAccessibility() + + NotificationCenter.default.addObserver(self, selector: #selector(voiceoverStatusDidChange), name: UIAccessibility.voiceOverStatusDidChangeNotification, object: nil) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -151,4 +153,15 @@ class StopAnnotationView: MKAnnotationView { /// Foreground color for text written directly onto the map as part of this annotation view. public var mapTextColor: UIColor = ThemeColors.shared.mapText + + // MARK: - Accessibility + @objc fileprivate func voiceoverStatusDidChange(_ notification: Notification) { + updateAccessibility() + } + + fileprivate func updateAccessibility() { + // Callouts are finicky when in VoiceOver. When VoiceOver is running, + // we should skip the callout and push directly to the annotation's destination view. + canShowCallout = !UIAccessibility.isVoiceOverRunning + } }