diff options
author | Julian Rex <julian.rex@gmail.com> | 2018-03-21 13:51:10 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-21 13:51:10 -0400 |
commit | d4f2bc07ca424fe6c4a596dac91ab247634e7aab (patch) | |
tree | c41ac7519c8c0ddca43faa61b345a56b0fa32058 /platform/ios/app | |
parent | 4b3d0638b8029421c0fb3f380f4d482cfd74f00e (diff) | |
download | qtlocation-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.m | 7 | ||||
-rw-r--r-- | platform/ios/app/MBXViewController.m | 93 |
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]; } } |