diff options
author | Minh Nguyễn <mxn@1ec5.org> | 2016-04-17 16:43:05 -0700 |
---|---|---|
committer | Minh Nguyễn <mxn@1ec5.org> | 2016-04-19 14:24:59 -0700 |
commit | 8a4c2d4b0e9e39f0f183bc1b9aa549b9d65309bb (patch) | |
tree | e8ea0040f460f90cb1a98f0e5b9e9abbcf0a0d6c /platform | |
parent | 7a5406bc5022d7fcdc92590012af7636155a49c7 (diff) | |
download | qtlocation-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.
Diffstat (limited to 'platform')
-rw-r--r-- | platform/ios/CHANGELOG.md | 1 | ||||
-rw-r--r-- | platform/ios/app/MBXViewController.m | 11 | ||||
-rw-r--r-- | platform/ios/src/MGLMapView.mm | 29 |
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()) |