summaryrefslogtreecommitdiff
path: root/platform/ios/app
diff options
context:
space:
mode:
authorJulian Rex <julian.rex@gmail.com>2018-03-21 13:51:10 -0400
committerGitHub <noreply@github.com>2018-03-21 13:51:10 -0400
commitd4f2bc07ca424fe6c4a596dac91ab247634e7aab (patch)
treec41ac7519c8c0ddca43faa61b345a56b0fa32058 /platform/ios/app
parent4b3d0638b8029421c0fb3f380f4d482cfd74f00e (diff)
downloadqtlocation-mapboxgl-d4f2bc07ca424fe6c4a596dac91ab247634e7aab.tar.gz
[ios,macos] Selecting offscreen annotation pans map to fit annotation & callout view (#3249, #9790)
Diffstat (limited to 'platform/ios/app')
-rw-r--r--platform/ios/app/MBXCustomCalloutView.m7
-rw-r--r--platform/ios/app/MBXViewController.m93
2 files changed, 97 insertions, 3 deletions
diff --git a/platform/ios/app/MBXCustomCalloutView.m b/platform/ios/app/MBXCustomCalloutView.m
index 13564c5cbf..0626b0997a 100644
--- a/platform/ios/app/MBXCustomCalloutView.m
+++ b/platform/ios/app/MBXCustomCalloutView.m
@@ -37,11 +37,15 @@ static CGFloat const tipWidth = 10.0;
return self;
}
-
#pragma mark - API
- (void)presentCalloutFromRect:(CGRect)rect inView:(UIView *)view constrainedToView:(UIView *)constrainedView animated:(BOOL)animated
{
+ [self presentCalloutFromRect:rect inView:view constrainedToRect:CGRectNull animated:animated];
+}
+
+- (void)presentCalloutFromRect:(CGRect)rect inView:(nonnull UIView *)view constrainedToRect:(__unused CGRect)constrainedRect animated:(BOOL)animated
+{
if ([self.delegate respondsToSelector:@selector(calloutViewWillAppear:)])
{
[self.delegate performSelector:@selector(calloutViewWillAppear:) withObject:self];
@@ -108,5 +112,4 @@ static CGFloat const tipWidth = 10.0;
CGPathRelease(tipPath);
}
-
@end
diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m
index a472e3a221..5282469223 100644
--- a/platform/ios/app/MBXViewController.m
+++ b/platform/ios/app/MBXViewController.m
@@ -54,6 +54,9 @@ typedef NS_ENUM(NSInteger, MBXSettingsAnnotationsRows) {
MBXSettingsAnnotationsQueryAnnotations,
MBXSettingsAnnotationsCustomUserDot,
MBXSettingsAnnotationsRemoveAnnotations,
+ MBXSettingsAnnotationSelectRandomOffscreenPointAnnotation,
+ MBXSettingsAnnotationCenterSelectedAnnotation,
+ MBXSettingsAnnotationAddVisibleAreaPolyline
};
typedef NS_ENUM(NSInteger, MBXSettingsRuntimeStylingRows) {
@@ -340,6 +343,9 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
@"Query Annotations",
[NSString stringWithFormat:@"%@ Custom User Dot", (_customUserLocationAnnnotationEnabled ? @"Disable" : @"Enable")],
@"Remove Annotations",
+ @"Select an offscreen point annotation",
+ @"Center selected annotation",
+ @"Add visible area polyline"
]];
break;
case MBXSettingsRuntimeStyling:
@@ -468,6 +474,18 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
case MBXSettingsAnnotationsRemoveAnnotations:
[self.mapView removeAnnotations:self.mapView.annotations];
break;
+ case MBXSettingsAnnotationSelectRandomOffscreenPointAnnotation:
+ [self selectAnOffscreenPointAnnotation];
+ break;
+
+ case MBXSettingsAnnotationCenterSelectedAnnotation:
+ [self centerSelectedAnnotation];
+ break;
+
+ case MBXSettingsAnnotationAddVisibleAreaPolyline:
+ [self addVisibleAreaPolyline];
+ break;
+
default:
NSAssert(NO, @"All annotations setting rows should be implemented");
break;
@@ -1551,6 +1569,73 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
[self presentViewController:alertController animated:YES completion:nil];
}
+- (id<MGLAnnotation>)randomOffscreenPointAnnotation {
+
+ NSPredicate *pointAnnotationPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
+ return [evaluatedObject isKindOfClass:[MGLPointAnnotation class]];
+ }];
+
+ NSArray *annotations = [self.mapView.annotations filteredArrayUsingPredicate:pointAnnotationPredicate];
+
+ if (annotations.count == 0) {
+ return nil;
+ }
+
+ NSArray *visibleAnnotations = [self.mapView.visibleAnnotations filteredArrayUsingPredicate:pointAnnotationPredicate];
+
+ if (visibleAnnotations.count == annotations.count) {
+ return nil;
+ }
+
+ NSMutableArray *invisibleAnnotations = [annotations mutableCopy];
+
+ if (visibleAnnotations.count > 0) {
+ [invisibleAnnotations removeObjectsInArray:visibleAnnotations];
+ }
+
+ // Now pick a random offscreen annotation.
+ uint32_t index = arc4random_uniform((uint32_t)invisibleAnnotations.count);
+ return invisibleAnnotations[index];
+}
+
+- (void)selectAnOffscreenPointAnnotation {
+ id<MGLAnnotation> annotation = [self randomOffscreenPointAnnotation];
+ if (annotation) {
+ [self.mapView selectAnnotation:annotation animated:YES];
+
+ NSAssert(self.mapView.selectedAnnotations.firstObject, @"The annotation was not selected");
+ }
+}
+
+- (void)centerSelectedAnnotation {
+ id<MGLAnnotation> annotation = self.mapView.selectedAnnotations.firstObject;
+
+ if (!annotation)
+ return;
+
+ CGPoint point = [self.mapView convertCoordinate:annotation.coordinate toPointToView:self.mapView];
+
+ // Animate, so that point becomes the the center
+ CLLocationCoordinate2D center = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
+ [self.mapView setCenterCoordinate:center animated:YES];
+}
+
+- (void)addVisibleAreaPolyline {
+ CGRect constrainedRect = UIEdgeInsetsInsetRect(self.mapView.bounds, self.mapView.contentInset);
+
+ CLLocationCoordinate2D lineCoords[5];
+
+ lineCoords[0] = [self.mapView convertPoint: CGPointMake(CGRectGetMinX(constrainedRect), CGRectGetMinY(constrainedRect)) toCoordinateFromView:self.mapView];
+ lineCoords[1] = [self.mapView convertPoint: CGPointMake(CGRectGetMaxX(constrainedRect), CGRectGetMinY(constrainedRect)) toCoordinateFromView:self.mapView];
+ lineCoords[2] = [self.mapView convertPoint: CGPointMake(CGRectGetMaxX(constrainedRect), CGRectGetMaxY(constrainedRect)) toCoordinateFromView:self.mapView];
+ lineCoords[3] = [self.mapView convertPoint: CGPointMake(CGRectGetMinX(constrainedRect), CGRectGetMaxY(constrainedRect)) toCoordinateFromView:self.mapView];
+ lineCoords[4] = lineCoords[0];
+
+ MGLPolyline *line = [MGLPolyline polylineWithCoordinates:lineCoords
+ count:sizeof(lineCoords)/sizeof(lineCoords[0])];
+ [self.mapView addAnnotation:line];
+}
+
- (void)printTelemetryLogFile
{
NSString *fileContents = [NSString stringWithContentsOfFile:[self telemetryDebugLogFilePath] encoding:NSUTF8StringEncoding error:nil];
@@ -1602,7 +1687,13 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
toCoordinateFromView:self.mapView];
pin.title = title ?: @"Dropped Pin";
pin.subtitle = [[[MGLCoordinateFormatter alloc] init] stringFromCoordinate:pin.coordinate];
- // Calling `addAnnotation:` on mapView is not required since `selectAnnotation:animated` has the side effect of adding the annotation if required
+
+
+ // Calling `addAnnotation:` on mapView is required here (since `selectAnnotation:animated` has
+ // the side effect of adding the annotation if required, but returning an incorrect callout
+ // positioning rect)
+
+ [self.mapView addAnnotation:pin];
[self.mapView selectAnnotation:pin animated:YES];
}
}