From 71611ec61247593aa6e9b568595114647363532d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Wed, 10 Feb 2016 09:34:19 -0800 Subject: [ios, osx] Fixed crash reselecting annotation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Handle the case where the currently selected annotation isn’t one of the nearby annotations. This hasn’t come up before on OS X because clicking an annotation while another annotation is selected only dismisses the callout popover. Fixes #3284. --- CHANGELOG.md | 1 + platform/ios/src/MGLMapView.mm | 21 +++++++++++++++------ platform/osx/src/MGLMapView.mm | 18 ++++++++++++------ 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 418d5c1ce7..ebb4e0f498 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ Known issues: - Corrected the dynamic framework’s minimum deployment target to iOS 8.0. ([#3872](https://github.com/mapbox/mapbox-gl-native/pull/3872)) - Fixed Fabric compatibility. ([#3847](https://github.com/mapbox/mapbox-gl-native/pull/3847)) +- Fixed a crash that can occur when reselecting an annotation. ([#3881](https://github.com/mapbox/mapbox-gl-native/pull/3881)) - Fixed an issue preventing `-[MGLMapViewDelegate mapView:tapOnCalloutForAnnotation:]` from being called when a non-custom callout view is tapped. ([#3875](https://github.com/mapbox/mapbox-gl-native/pull/3875)) ## iOS 3.1.0 diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 2040c40da5..bb71a4c63a 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -2698,19 +2698,28 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) if (_selectedAnnotationTag == MGLAnnotationTagNotFound || _selectedAnnotationTag == _annotationsNearbyLastTap.back()) { - // Either an annotation from this set hasn’t been selected - // before or the last annotation in the set was selected. Wrap - // around to the first annotation in the set. + // Either no annotation is selected or the last annotation in + // the set was selected. Wrap around to the first annotation in + // the set. hitAnnotationTag = _annotationsNearbyLastTap.front(); } else { - // Step to the next annotation in the set. auto result = std::find(_annotationsNearbyLastTap.begin(), _annotationsNearbyLastTap.end(), _selectedAnnotationTag); - auto distance = std::distance(_annotationsNearbyLastTap.begin(), result); - hitAnnotationTag = _annotationsNearbyLastTap[distance + 1]; + if (result == _annotationsNearbyLastTap.end()) + { + // An annotation from this set hasn’t been selected before. + // Select the first (nearest) one. + hitAnnotationTag = _annotationsNearbyLastTap.front(); + } + else + { + // Step to the next annotation in the set. + auto distance = std::distance(_annotationsNearbyLastTap.begin(), result); + hitAnnotationTag = _annotationsNearbyLastTap[distance + 1]; + } } } else diff --git a/platform/osx/src/MGLMapView.mm b/platform/osx/src/MGLMapView.mm index 3a92c1901d..065a3a00c2 100644 --- a/platform/osx/src/MGLMapView.mm +++ b/platform/osx/src/MGLMapView.mm @@ -1757,17 +1757,23 @@ public: // set of annotations as we do now. Cycle through them. if (_lastSelectedAnnotationTag == MGLAnnotationTagNotFound || _lastSelectedAnnotationTag == _annotationsNearbyLastClick.back()) { - // Either an annotation from this set hasn’t been selected - // before or the last annotation in the set was selected. Wrap - // around to the first annotation in the set. + // Either no annotation is selected or the last annotation in + // the set was selected. Wrap around to the first annotation in + // the set. hitAnnotationTag = _annotationsNearbyLastClick.front(); } else { - // Step to the next annotation in the set. auto result = std::find(_annotationsNearbyLastClick.begin(), _annotationsNearbyLastClick.end(), _lastSelectedAnnotationTag); - auto distance = std::distance(_annotationsNearbyLastClick.begin(), result); - hitAnnotationTag = _annotationsNearbyLastClick[distance + 1]; + if (result == _annotationsNearbyLastClick.end()) { + // An annotation from this set hasn’t been selected before. + // Select the first (nearest) one. + hitAnnotationTag = _annotationsNearbyLastClick.front(); + } else { + // Step to the next annotation in the set. + auto distance = std::distance(_annotationsNearbyLastClick.begin(), result); + hitAnnotationTag = _annotationsNearbyLastClick[distance + 1]; + } } } else { // Remember the nearby annotations for the next time this method is -- cgit v1.2.1