Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Refactored MGLUserLocationAnnotationView (redux) #5882

Merged
merged 23 commits into from
Aug 16, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0793394
[ios] #5039 MGLUserLocationAnnotationView now inherits from MGLAnnota…
frederoni Jul 5, 2016
68e2e4c
[ios] WiP refactored user location annotation view
frederoni Jul 7, 2016
18af28e
[ios] cleanup, put headers in the appropriate scope, added comments
frederoni Jul 8, 2016
6f50e50
update frame before setting up layers
frederoni Jul 11, 2016
e56ce6c
[ios] allow mbgl to drive animation of all user location view's bounds.
frederoni Jul 11, 2016
0ce1195
[ios] updated user location view in the demo app
frederoni Jul 11, 2016
ef8cf2a
[ios] removed unused import
frederoni Jul 11, 2016
179aa65
added MGLUserLocationAnnotationView to jazzy
frederoni Jul 12, 2016
f40c72c
[ios] Add MGLUserLocationAnnotationView.hitTestLayer property
friedbunny Aug 5, 2016
c863546
Clean up hitLayer logic
friedbunny Aug 7, 2016
5903b81
Use a more specific test for a custom hit test layer
friedbunny Aug 12, 2016
ff9fd2f
Remove unused code
friedbunny Aug 12, 2016
5a65c8b
Move haloLayer into the private implementation def
friedbunny Aug 12, 2016
d7e0c5b
Only update frame size if not already set
friedbunny Aug 12, 2016
9f06753
Change to a plain `update` method, call it more frequently
friedbunny Aug 12, 2016
ca895ec
Give greater depth to documentation for `update` method
friedbunny Aug 13, 2016
652aecb
Be less severe: @warning → @note
friedbunny Aug 13, 2016
4687516
Fix example's accuracy in dot frame sizing
friedbunny Aug 13, 2016
b6e2a49
Remove one letter, because it was bothering me...
friedbunny Aug 13, 2016
c46d79e
Re-add empty implementation of `update` with subclassing note
friedbunny Aug 13, 2016
412214d
Accept Xcode's project file rearrangement
friedbunny Aug 13, 2016
634f680
Add toggle in iosapp for custom user location annotation
friedbunny Aug 15, 2016
3dd2179
Update changelog for customizable user location annotations
friedbunny Aug 16, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions platform/ios/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
## master

* A new runtime styling API allows you to adjust the style and content of the base map dynamically. All the options available in [Mapbox Studio](https://www.mapbox.com/studio/) are now exposed via MGLStyle and subclasses of MGLStyleLayer and MGLSource. ([#5727](https://github.com/mapbox/mapbox-gl-native/pull/5727))
* The user location annotation is now customizable via the newly added `MGLUserLocationAnnotationView` class. ([#5882](https://github.com/mapbox/mapbox-gl-native/pull/5882))
* Simulator architecture slices are included in the included dSYM file, allowing you to symbolicate crashes that occur in the Simulator. ([#5740](https://github.com/mapbox/mapbox-gl-native/pull/5740))
* As the user zooms in, tiles from lower zoom levels are scaled up until tiles for higher zoom levels are loaded. ([#5143](https://github.com/mapbox/mapbox-gl-native/pull/5143))
* Fixed an issue causing the wrong annotation view to be selected when tapping an annotation view with a center offset applied. ([#5931](https://github.com/mapbox/mapbox-gl-native/pull/5931))
Expand Down
5 changes: 5 additions & 0 deletions platform/ios/app/MBXUserLocationAnnotationView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#import <Mapbox/Mapbox.h>

@interface MBXUserLocationAnnotationView : MGLUserLocationAnnotationView

@end
165 changes: 165 additions & 0 deletions platform/ios/app/MBXUserLocationAnnotationView.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
#import "MBXUserLocationAnnotationView.h"

const CGFloat MBXUserLocationDotSize = 10;

@implementation MBXUserLocationAnnotationView

- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self == nil) return nil;
self.backgroundColor = [UIColor clearColor];
return self;
}

- (void)update
{
[self updateFrameWithSize:self.intrinsicContentSize];
[self setNeedsDisplay];
}


- (CGSize)intrinsicContentSize
{
CGSize carSize = CGSizeMake(30, 60);
return (self.mapView.userTrackingMode == MGLUserTrackingModeFollowWithCourse) ? carSize : [self dotSize];
}

- (CGSize)dotSize
{
CGFloat minDotSize = 30;
CGFloat dotSize = MAX(minDotSize, self.accuracyInPoints);
return CGSizeMake(dotSize, dotSize);
}

- (void)updateFrameWithSize:(CGSize)size
{
if (CGSizeEqualToSize(self.frame.size, size)) return;

// Update frame size, keeping the existing center point.
CGRect newFrame = self.frame;
CGPoint oldCenter = self.center;
newFrame.size = size;
self.frame = newFrame;
self.center = oldCenter;
}

- (CGFloat)accuracyInPoints
{
CGFloat metersPerPoint = [self.mapView metersPerPointAtLatitude:self.userLocation.location.coordinate.latitude];
return self.userLocation.location.horizontalAccuracy / metersPerPoint;
}

- (void)drawRect:(CGRect)rect
{
(self.mapView.userTrackingMode == MGLUserTrackingModeFollowWithCourse) ? [self drawCar] : [self drawDot];
}

- (void)drawDot
{
// Accuracy
CGFloat accuracy = self.accuracyInPoints;

CGFloat center = self.bounds.size.width / 2.0 - accuracy / 2.0;
UIBezierPath *accuracyPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(center, center, accuracy, accuracy)];
UIColor *accuracyColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:.4];
[accuracyColor setFill];
[accuracyPath fill];

// Dot
center = self.bounds.size.width / 2.0 - MBXUserLocationDotSize / 2.0;
UIBezierPath *ovalPath = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(center, center, MBXUserLocationDotSize, MBXUserLocationDotSize)];
[UIColor.greenColor setFill];
[ovalPath fill];

[UIColor.blackColor setStroke];
ovalPath.lineWidth = 1;
[ovalPath stroke];

// Accuracy text
UIFont *font = [UIFont systemFontOfSize:11];
[[NSString stringWithFormat:@"%.0f", accuracy]
drawAtPoint:CGPointZero withAttributes:@{NSFontAttributeName: font,
NSBackgroundColorAttributeName: [UIColor colorWithWhite:0 alpha:.5],
NSForegroundColorAttributeName: [UIColor whiteColor]}];
}

- (void)drawCar
{
UIColor* fillColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 1];
UIColor* strokeColor = [UIColor colorWithRed: 0.592 green: 0.592 blue: 0.592 alpha: 1];
UIColor* fillColor2 = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1];

UIBezierPath* bezier2Path = [UIBezierPath bezierPath];
[bezier2Path moveToPoint: CGPointMake(30, 7.86)];
[bezier2Path addLineToPoint: CGPointMake(30, 52.66)];
[bezier2Path addCurveToPoint: CGPointMake(0, 52.66) controlPoint1: CGPointMake(30, 62.05) controlPoint2: CGPointMake(0, 62.84)];
[bezier2Path addCurveToPoint: CGPointMake(0, 7.86) controlPoint1: CGPointMake(0, 42.48) controlPoint2: CGPointMake(0, 17.89)];
[bezier2Path addCurveToPoint: CGPointMake(30, 7.86) controlPoint1: CGPointMake(-0, -2.17) controlPoint2: CGPointMake(30, -3.05)];
[bezier2Path closePath];
bezier2Path.usesEvenOddFillRule = YES;

[fillColor setFill];
[bezier2Path fill];

UIBezierPath* bezier3Path = [UIBezierPath bezierPath];
[bezier3Path moveToPoint: CGPointMake(30, 7.86)];
[bezier3Path addLineToPoint: CGPointMake(30, 52.66)];
[bezier3Path addCurveToPoint: CGPointMake(0, 52.66) controlPoint1: CGPointMake(30, 62.05) controlPoint2: CGPointMake(0, 62.84)];
[bezier3Path addCurveToPoint: CGPointMake(0, 7.86) controlPoint1: CGPointMake(0, 42.48) controlPoint2: CGPointMake(0, 17.89)];
[bezier3Path addCurveToPoint: CGPointMake(30, 7.86) controlPoint1: CGPointMake(0, -2.17) controlPoint2: CGPointMake(30, -3.05)];
[bezier3Path closePath];
[strokeColor setStroke];
bezier3Path.lineWidth = 1;
[bezier3Path stroke];

UIBezierPath* bezier4Path = [UIBezierPath bezierPath];
[bezier4Path moveToPoint: CGPointMake(15.56, 4.26)];
[bezier4Path addCurveToPoint: CGPointMake(26, 6) controlPoint1: CGPointMake(21, 4.26) controlPoint2: CGPointMake(26, 6)];
[bezier4Path addCurveToPoint: CGPointMake(23, 21) controlPoint1: CGPointMake(26, 6) controlPoint2: CGPointMake(29, 17)];
[bezier4Path addCurveToPoint: CGPointMake(16, 21) controlPoint1: CGPointMake(20.03, 22.98) controlPoint2: CGPointMake(16, 21)];
[bezier4Path addCurveToPoint: CGPointMake(7, 21) controlPoint1: CGPointMake(16, 21) controlPoint2: CGPointMake(9.02, 23.53)];
[bezier4Path addCurveToPoint: CGPointMake(4, 6) controlPoint1: CGPointMake(3, 16) controlPoint2: CGPointMake(4, 6)];
[bezier4Path addCurveToPoint: CGPointMake(15.56, 4.26) controlPoint1: CGPointMake(4, 6) controlPoint2: CGPointMake(10.12, 4.26)];
[bezier4Path closePath];
bezier4Path.usesEvenOddFillRule = YES;

[fillColor2 setFill];
[bezier4Path fill];

UIBezierPath* rectanglePath = [UIBezierPath bezierPath];
[rectanglePath moveToPoint: CGPointMake(25, 46)];
[rectanglePath addCurveToPoint: CGPointMake(21, 55) controlPoint1: CGPointMake(31, 46) controlPoint2: CGPointMake(28.5, 55)];
[rectanglePath addCurveToPoint: CGPointMake(9, 55) controlPoint1: CGPointMake(13.5, 55) controlPoint2: CGPointMake(14, 55)];
[rectanglePath addCurveToPoint: CGPointMake(5, 46) controlPoint1: CGPointMake(4, 55) controlPoint2: CGPointMake(0, 46)];
[rectanglePath addCurveToPoint: CGPointMake(25, 46) controlPoint1: CGPointMake(10, 46) controlPoint2: CGPointMake(19, 46)];
[rectanglePath closePath];
[UIColor.whiteColor setFill];
[rectanglePath fill];

UIBezierPath* bezierPath = [UIBezierPath bezierPath];
[UIColor.whiteColor setFill];
[bezierPath fill];

UIBezierPath* rectangle2Path = [UIBezierPath bezierPath];
[rectangle2Path moveToPoint: CGPointMake(2, 35)];
[rectangle2Path addCurveToPoint: CGPointMake(4.36, 35) controlPoint1: CGPointMake(2, 39) controlPoint2: CGPointMake(4.36, 35)];
[rectangle2Path addCurveToPoint: CGPointMake(4.36, 22) controlPoint1: CGPointMake(4.36, 35) controlPoint2: CGPointMake(5.55, 26)];
[rectangle2Path addCurveToPoint: CGPointMake(2, 22) controlPoint1: CGPointMake(3.18, 18) controlPoint2: CGPointMake(2, 22)];
[rectangle2Path addCurveToPoint: CGPointMake(2, 35) controlPoint1: CGPointMake(2, 22) controlPoint2: CGPointMake(2, 31)];
[rectangle2Path closePath];
[UIColor.whiteColor setFill];
[rectangle2Path fill];

UIBezierPath* rectangle3Path = [UIBezierPath bezierPath];
[rectangle3Path moveToPoint: CGPointMake(28, 35)];
[rectangle3Path addCurveToPoint: CGPointMake(25.64, 35) controlPoint1: CGPointMake(28, 39) controlPoint2: CGPointMake(25.64, 35)];
[rectangle3Path addCurveToPoint: CGPointMake(25.64, 22) controlPoint1: CGPointMake(25.64, 35) controlPoint2: CGPointMake(24.45, 26)];
[rectangle3Path addCurveToPoint: CGPointMake(28, 22) controlPoint1: CGPointMake(26.82, 18) controlPoint2: CGPointMake(28, 22)];
[rectangle3Path addCurveToPoint: CGPointMake(28, 35) controlPoint1: CGPointMake(28, 22) controlPoint2: CGPointMake(28, 31)];
[rectangle3Path closePath];
[UIColor.whiteColor setFill];
[rectangle3Path fill];
}

@end
24 changes: 23 additions & 1 deletion platform/ios/app/MBXViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#import "MBXCustomCalloutView.h"
#import "MBXOfflinePacksTableViewController.h"
#import "MBXAnnotationView.h"
#import "MBXUserLocationAnnotationView.h"
#import "MGLFillStyleLayer.h"

#import <Mapbox/Mapbox.h>
Expand Down Expand Up @@ -42,6 +43,7 @@ @interface MBXViewController () <UIActionSheetDelegate, MGLMapViewDelegate>
@property (nonatomic) IBOutlet MGLMapView *mapView;
@property (nonatomic) NSInteger styleIndex;
@property (nonatomic) BOOL debugLoggingEnabled;
@property (nonatomic) BOOL customUserLocationAnnnotationEnabled;

@end

Expand Down Expand Up @@ -201,7 +203,10 @@ - (IBAction)showSettings:(__unused id)sender
@"Start World Tour",
@"Add Custom Callout Point",
@"Remove Annotations",
@"Runtime styling",
@"Runtime Styling",
((_customUserLocationAnnnotationEnabled)
? @"Disable Custom User Dot"
: @"Enable Custom User Dot"),
nil];

if (self.debugLoggingEnabled)
Expand Down Expand Up @@ -283,6 +288,12 @@ - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSIn
{
[self testRuntimeStyling];
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 17)
{
_customUserLocationAnnnotationEnabled = !_customUserLocationAnnnotationEnabled;
self.mapView.showsUserLocation = NO;
self.mapView.userTrackingMode = MGLUserTrackingModeFollow;
}
else if (buttonIndex == actionSheet.numberOfButtons - 2 && self.debugLoggingEnabled)
{
NSString *fileContents = [NSString stringWithContentsOfFile:[self telemetryDebugLogfilePath] encoding:NSUTF8StringEncoding error:nil];
Expand Down Expand Up @@ -699,6 +710,17 @@ - (void)dealloc

- (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id<MGLAnnotation>)annotation
{
if (annotation == mapView.userLocation)
{
if (_customUserLocationAnnnotationEnabled)
{
MBXUserLocationAnnotationView *annotationView = [[MBXUserLocationAnnotationView alloc] initWithFrame:CGRectZero];
annotationView.frame = CGRectMake(0, 0, annotationView.intrinsicContentSize.width, annotationView.intrinsicContentSize.height);
return annotationView;
}

return nil;
}
// Use GL backed pins for dropped pin annotations
if ([annotation isKindOfClass:[MBXDroppedPinAnnotation class]] || [annotation isKindOfClass:[MBXSpriteBackedAnnotation class]])
{
Expand Down
Loading