summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Rex <julian.rex@mapbox.com>2018-09-25 21:58:59 -0400
committerJulian Rex <julian.rex@mapbox.com>2018-10-06 00:58:40 -0400
commit5bfe397a176cd72e80296b3bc24b5af654b8e987 (patch)
tree5f4a634f7ecfa6778c058f8843f977e8aa83bb48
parent91ea258dde2a715170da2850e327507b77eff6c6 (diff)
downloadqtlocation-mapboxgl-5bfe397a176cd72e80296b3bc24b5af654b8e987.tar.gz
Added WIP delegate methods to handle annotations' selection animations and behaviour
-rw-r--r--platform/ios/src/MGLMapView.h12
-rw-r--r--platform/ios/src/MGLMapView.mm63
-rw-r--r--platform/ios/src/MGLMapViewDelegate.h29
3 files changed, 79 insertions, 25 deletions
diff --git a/platform/ios/src/MGLMapView.h b/platform/ios/src/MGLMapView.h
index 5312804cd2..8fdd346379 100644
--- a/platform/ios/src/MGLMapView.h
+++ b/platform/ios/src/MGLMapView.h
@@ -1318,6 +1318,10 @@ MGL_EXPORT IB_DESIGNABLE
@property (nonatomic, copy) NSArray<id <MGLAnnotation>> *selectedAnnotations;
/**
+ TODO: update documentation
+ TODO: consider deprecation, and replacing with a `selectAnnotation:` that uses the proposed delegate
+ methods.
+
Selects an annotation and displays its callout view.
The `animated` parameter determines whether the map is panned to bring the
@@ -1325,14 +1329,18 @@ MGL_EXPORT IB_DESIGNABLE
| `animated` parameter | Effect |
|------------------|--------|
- | `NO` | The annotation is selected, and the callout is presented. However the map is not panned to bring the annotation or callout onscreen. The presentation of the callout is animated. |
+ | `NO` | The annotation is selected, and the callout is presented. However the map is not panned to bring the annotation or callout onscreen.
| `YES` | The annotation is selected, and the callout is presented. If the annotation is offscreen *and* is of type `MGLPointAnnotation`, the map is panned so that the annotation and its callout are brought just onscreen. The annotation is *not* centered within the viewport. |
@param annotation The annotation object to select.
- @param animated If `YES`, the annotation and callout view are animated on-screen.
+ @param animated If `YES`, the annotation and callout view are moved on-screen.
@note In versions prior to `4.0.0` selecting an offscreen annotation did not
change the camera.
+
+ @note The `animated` parameter can be considered the same as the value returned from
+ `-[MGLMapViewDelgate mapView:shouldMoveOnscreenWhenSelectingAnnotation:]`.
+ See also `-[MGLMapViewDelegate mapView:shouldAnimateAnnotationSelection:` for animation control
*/
- (void)selectAnnotation:(id <MGLAnnotation>)annotation animated:(BOOL)animated;
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index e9fd568a04..b68b0f4352 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -1712,7 +1712,14 @@ public:
{
CGPoint calloutPoint = [singleTap locationInView:self];
CGRect positionRect = [self positioningRectForAnnotation:annotation defaultCalloutPoint:calloutPoint];
- [self selectAnnotation:annotation moveOnscreen:YES animateSelection:YES calloutPositioningRect:positionRect];
+
+ BOOL moveOnscreen = YES;
+
+ if ([self.delegate respondsToSelector:@selector(mapView:shouldMoveOnscreenWhenSelectingAnnotation:)]) {
+ moveOnscreen = [self.delegate mapView:self shouldMoveOnscreenWhenSelectingAnnotation:annotation];
+ }
+
+ [self selectAnnotation:annotation moveOnscreen:moveOnscreen calloutPositioningRect:positionRect];
}
else if (self.selectedAnnotation)
{
@@ -4370,10 +4377,11 @@ public:
- (void)selectAnnotation:(id <MGLAnnotation>)annotation animated:(BOOL)animated
{
CGRect positioningRect = [self positioningRectForAnnotation:annotation defaultCalloutPoint:CGPointZero];
- [self selectAnnotation:annotation moveOnscreen:animated animateSelection:YES calloutPositioningRect:positioningRect];
+
+ [self selectAnnotation:annotation moveOnscreen:animated calloutPositioningRect:positioningRect];
}
-- (void)selectAnnotation:(id <MGLAnnotation>)annotation moveOnscreen:(BOOL)moveOnscreen animateSelection:(BOOL)animateSelection calloutPositioningRect:(CGRect)calloutPositioningRect
+- (void)selectAnnotation:(id <MGLAnnotation>)annotation moveOnscreen:(BOOL)moveOnscreen calloutPositioningRect:(CGRect)calloutPositioningRect
{
if ( ! annotation) return;
@@ -4381,6 +4389,12 @@ public:
[self deselectAnnotation:self.selectedAnnotation animated:NO];
+ BOOL animateSelection = YES;
+
+ if ([self.delegate respondsToSelector:@selector(mapView:shouldAnimateAnnotationSelection:)]) {
+ animateSelection = [self.delegate mapView:self shouldAnimateAnnotationSelection:annotation];
+ }
+
// Add the annotation to the map if it hasn’t been added yet.
MGLAnnotationTag annotationTag = [self annotationTagForAnnotation:annotation];
if (annotationTag == MGLAnnotationTagNotFound && annotation != self.userLocation)
@@ -4407,11 +4421,6 @@ public:
self.selectedAnnotation = annotation;
- // Determine if we're allowed to move this offscreen annotation on screen, even though we've asked it to
- if (moveOnscreen) {
- moveOnscreen = [self isBringingAnnotationOnscreenSupportedForAnnotation:annotation animated:animateSelection];
- }
-
// If we have an invalid positioning rect, we need to provide a suitable default.
// This (currently) happens if you select an annotation that has NOT yet been
// added. See https://github.com/mapbox/mapbox-gl-native/issues/11476
@@ -4504,29 +4513,37 @@ public:
moveOnscreen = NO;
// Need to consider the content insets.
- CGRect bounds = UIEdgeInsetsInsetRect(self.bounds, self.contentInset);
+ CGRect bounds = constrainedRect;
// Any one of these cases should trigger a move onscreen
- if (CGRectGetMinX(calloutPositioningRect) < CGRectGetMinX(bounds))
- {
- constrainedRect.origin.x = expandedPositioningRect.origin.x;
+ CGFloat minX = CGRectGetMinX(expandedPositioningRect);
+
+ if (minX < CGRectGetMinX(bounds)) {
+ constrainedRect.origin.x = minX;
moveOnscreen = YES;
}
- else if (CGRectGetMaxX(calloutPositioningRect) > CGRectGetMaxX(bounds))
- {
- constrainedRect.origin.x = CGRectGetMaxX(expandedPositioningRect) - constrainedRect.size.width;
- moveOnscreen = YES;
+ else {
+ CGFloat maxX = CGRectGetMaxX(expandedPositioningRect);
+
+ if (maxX > CGRectGetMaxX(bounds)) {
+ constrainedRect.origin.x = maxX - CGRectGetWidth(constrainedRect);
+ moveOnscreen = YES;
+ }
}
- if (CGRectGetMinY(calloutPositioningRect) < CGRectGetMinY(bounds))
- {
- constrainedRect.origin.y = expandedPositioningRect.origin.y;
+ CGFloat minY = CGRectGetMinY(expandedPositioningRect);
+
+ if (minY < CGRectGetMinY(bounds)) {
+ constrainedRect.origin.y = minY;
moveOnscreen = YES;
}
- else if (CGRectGetMaxY(calloutPositioningRect) > CGRectGetMaxY(bounds))
- {
- constrainedRect.origin.y = CGRectGetMaxY(expandedPositioningRect) - constrainedRect.size.height;
- moveOnscreen = YES;
+ else {
+ CGFloat maxY = CGRectGetMaxY(expandedPositioningRect);
+
+ if (maxY > CGRectGetMaxY(bounds)) {
+ constrainedRect.origin.y = maxY - CGRectGetHeight(constrainedRect);
+ moveOnscreen = YES;
+ }
}
}
diff --git a/platform/ios/src/MGLMapViewDelegate.h b/platform/ios/src/MGLMapViewDelegate.h
index 77dd2e4ef4..596124ff93 100644
--- a/platform/ios/src/MGLMapViewDelegate.h
+++ b/platform/ios/src/MGLMapViewDelegate.h
@@ -459,6 +459,35 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (BOOL)mapView:(MGLMapView *)mapView shapeAnnotationIsEnabled:(MGLShape *)annotation;
+
+/**
+ TODO: document
+ Returns a Boolean value indicating whether the annotation should be moved on-screen.
+
+ If the delegate does not implement this method, the default is `YES`.
+
+ This method is useful in cases where the selection is not programmatic (e.g. user taps an annotation)
+ The value returned from this method can be considered the same as the `animated` parameter passed to
+ `-selectAnnotation:animated:`
+ */
+- (BOOL)mapView:(MGLMapView *)mapView shouldMoveOnscreenWhenSelectingAnnotation:(id <MGLAnnotation>)annotation;
+
+
+/**
+ TODO: document
+ Returns a Boolean value indicating whether the annotation's visual changes should be animated.
+ Specifically this controls:
+ - The annotation's selection change
+ - The presentation of the annotation's callout (if applicable)
+ - When moving an off-screen annotation, whether that movement is animated.
+
+ If the delegate does not implement this method, the default is `YES`.
+
+ The value returned from this method is NOT the same as the `animated` parameter passed to
+ `-selectAnnotation:animated:`
+ */
+- (BOOL)mapView:(MGLMapView *)mapView shouldAnimateAnnotationSelection:(id <MGLAnnotation>)annotation;
+
/**
Tells the delegate that one of its annotations was selected.