summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2016-04-17 16:43:05 -0700
committerMinh Nguyễn <mxn@1ec5.org>2016-04-19 14:24:59 -0700
commit8a4c2d4b0e9e39f0f183bc1b9aa549b9d65309bb (patch)
treee8ea0040f460f90cb1a98f0e5b9e9abbcf0a0d6c
parent7a5406bc5022d7fcdc92590012af7636155a49c7 (diff)
downloadqtlocation-mapboxgl-8a4c2d4b0e9e39f0f183bc1b9aa549b9d65309bb.tar.gz
[ios] Observe annotation coordinates
MGLMapView observes changes to the coordinate property of each MGLAnnotation added to it. Changing the coordinate property in a KVO-compliant way causes the annotation to be relocated and its callout view, if present, to be dismissed. To avoid observing the same annotation twice yet also avoid expensive lookups when adding or removing annotations, MGLMapView indexes added point annotations in an NSMutableSet. In iosapp, tapping a callout view moves the selected annotation to the center of the screen and deselects it. Fixes #1980.
-rw-r--r--platform/ios/CHANGELOG.md1
-rw-r--r--platform/ios/app/MBXViewController.m11
-rw-r--r--platform/ios/src/MGLMapView.mm29
3 files changed, 41 insertions, 0 deletions
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index c52e00be56..aa8fbd866c 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -8,6 +8,7 @@ Mapbox welcomes participation and contributions from everyone. If you’d like
- Removed the `armv7s` slice from the SDK to reduce its size. iPhone 5 and iPhone 5c automatically use the `armv7` slice instead. ([#4641](https://github.com/mapbox/mapbox-gl-native/pull/4641))
- The user dot now moves smoothly between user location updates while user location tracking is disabled. ([#1582](https://github.com/mapbox/mapbox-gl-native/pull/1582))
- User location heading updates now resume properly when an app becomes active again. ([#4674](https://github.com/mapbox/mapbox-gl-native/pull/4674))
+- An MGLAnnotation can be relocated by changing its `coordinate` property in a KVO-compliant way. ([#3835](https://github.com/mapbox/mapbox-gl-native/pull/3835))
- Setting the `image` property of an MGLAnnotationImage to `nil` resets it to the default red pin image and reclaims resources that can be used to customize additional annotations. ([#3835](https://github.com/mapbox/mapbox-gl-native/pull/3835))
- Fixed an issue preventing KVO change notifications from being generated on MGLMapView’s `userTrackingMode` key path when `-setUserTrackingMode:animated:` is called. ([#4724](https://github.com/mapbox/mapbox-gl-native/pull/4724))
- Fixed a hang that could occur if the host application attempts to set user defaults on a background queue. ([#4745](https://github.com/mapbox/mapbox-gl-native/pull/4745))
diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m
index 687bf64953..2f4caf9939 100644
--- a/platform/ios/app/MBXViewController.m
+++ b/platform/ios/app/MBXViewController.m
@@ -719,4 +719,15 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
return nil;
}
+- (void)mapView:(MGLMapView *)mapView tapOnCalloutForAnnotation:(id <MGLAnnotation>)annotation
+{
+ if ( ! [annotation isKindOfClass:[MGLPointAnnotation class]])
+ {
+ return;
+ }
+
+ MGLPointAnnotation *point = annotation;
+ point.coordinate = [self.mapView convertPoint:self.mapView.center toCoordinateFromView:self.mapView];
+}
+
@end
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 2120f2b7b6..44e3c37ac4 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -191,6 +191,7 @@ public:
NS_MUTABLE_ARRAY_OF(NSURL *) *_bundledStyleURLs;
MGLAnnotationContextMap _annotationContextsByAnnotationTag;
+ NS_MUTABLE_SET_OF(id <MGLAnnotation>) *_pointAnnotations;
/// Tag of the selected annotation. If the user location annotation is selected, this ivar is set to `MGLAnnotationTagNotFound`.
MGLAnnotationTag _selectedAnnotationTag;
BOOL _userLocationAnnotationIsSelected;
@@ -343,6 +344,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
// Set up annotation management and selection state.
_annotationImagesByIdentifier = [NSMutableDictionary dictionary];
_annotationContextsByAnnotationTag = {};
+ _pointAnnotations = [NSMutableSet set];
_selectedAnnotationTag = MGLAnnotationTagNotFound;
_annotationsNearbyLastTap = {};
@@ -1608,6 +1610,21 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
[MGLMapboxEvents ensureMetricsOptoutExists];
}
}
+ else if ([keyPath isEqualToString:@"coordinate"] && [object conformsToProtocol:@protocol(MGLAnnotation)])
+ {
+ id <MGLAnnotation> annotation = object;
+ MGLAnnotationTag annotationTag = [self annotationTagForAnnotation:annotation];
+ if (annotationTag != MGLAnnotationTagNotFound)
+ {
+ const mbgl::LatLng latLng = MGLLatLngFromLocationCoordinate2D(annotation.coordinate);
+ MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithTag:annotationTag];
+ _mbglMap->updatePointAnnotation(annotationTag, { latLng, annotationImage.styleIconIdentifier.UTF8String ?: "" });
+ if (annotationTag == _selectedAnnotationTag)
+ {
+ [self deselectAnnotation:annotation animated:YES];
+ }
+ }
+ }
}
+ (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingZoomEnabled
@@ -2417,6 +2434,12 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
[annotationImages addObject:annotationImage];
points.emplace_back(MGLLatLngFromLocationCoordinate2D(annotation.coordinate), symbolName.UTF8String ?: "");
+
+ if ( ! [_pointAnnotations containsObject:annotation] && [annotation isKindOfClass:[NSObject class]])
+ {
+ [(NSObject *)annotation addObserver:self forKeyPath:@"coordinate" options:0 context:NULL];
+ [_pointAnnotations addObject:annotation];
+ }
}
}
@@ -2571,6 +2594,12 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
}
_annotationContextsByAnnotationTag.erase(annotationTag);
+
+ if ([annotation isKindOfClass:[NSObject class]])
+ {
+ [(NSObject *)annotation removeObserver:self forKeyPath:@"coordinate"];
+ }
+ [_pointAnnotations removeObject:annotation];
}
if ( ! annotationTagsToRemove.empty())