From b35b328f5037283a2d3ffbf1981c7889dca59775 Mon Sep 17 00:00:00 2001 From: Nic Hubbard Date: Wed, 7 Jul 2021 18:14:56 -0700 Subject: [PATCH] scaleBar enhancements (#120) * Updated scaleBar to allow setting dark label styles which show up much better when using dark map styles. * Allows user to set if the scaleBar uses metric or not, rather than the system locale forcing this. This allows user flexability. * Add methods to mapView to access new scaleBar properties --- platform/ios/platform/ios/src/MGLMapView.h | 10 +++ platform/ios/platform/ios/src/MGLMapView.mm | 14 ++++ platform/ios/platform/ios/src/MGLScaleBar.h | 6 ++ platform/ios/platform/ios/src/MGLScaleBar.mm | 71 +++++++++++++++++--- 4 files changed, 93 insertions(+), 8 deletions(-) diff --git a/platform/ios/platform/ios/src/MGLMapView.h b/platform/ios/platform/ios/src/MGLMapView.h index 0910660a2..5f50ddbec 100644 --- a/platform/ios/platform/ios/src/MGLMapView.h +++ b/platform/ios/platform/ios/src/MGLMapView.h @@ -326,6 +326,16 @@ MGL_EXPORT */ @property (nonatomic, readonly) UIView *scaleBar; +/** + Sets whether the scale uses styles that make it easier to read on a dark styled map + */ +@property (nonatomic, assign) BOOL scaleBarShouldShowDarkStyles; + +/** + Sets whether the scale uses metric + */ +@property (nonatomic, assign) BOOL scaleBarUsesMetricSystem; + /** The position of the scale bar. The default value is `MGLOrnamentPositionTopLeft`. */ diff --git a/platform/ios/platform/ios/src/MGLMapView.mm b/platform/ios/platform/ios/src/MGLMapView.mm index 163937d5e..a7a5d0d2b 100644 --- a/platform/ios/platform/ios/src/MGLMapView.mm +++ b/platform/ios/platform/ios/src/MGLMapView.mm @@ -2979,6 +2979,20 @@ static void *windowScreenContext = &windowScreenContext; } } +- (void)setScaleBarShouldShowDarkStyles:(BOOL)scaleBarShouldShowDarkStyles { + + _scaleBarShouldShowDarkStyles = scaleBarShouldShowDarkStyles; + [(MGLScaleBar *)self.scaleBar setShouldShowDarkStyles:scaleBarShouldShowDarkStyles]; + +} + +- (void)setScaleBarUsesMetricSystem:(BOOL)scaleBarUsesMetricSystem { + + _scaleBarUsesMetricSystem = scaleBarUsesMetricSystem; + [(MGLScaleBar *)self.scaleBar setUsesMetricSystem:scaleBarUsesMetricSystem]; + +} + - (void)setPrefetchesTiles:(BOOL)prefetchesTiles { self.mbglMap.setPrefetchZoomDelta(prefetchesTiles ? mbgl::util::DEFAULT_PREFETCH_ZOOM_DELTA : 0); diff --git a/platform/ios/platform/ios/src/MGLScaleBar.h b/platform/ios/platform/ios/src/MGLScaleBar.h index 77fd6736b..197cd18cb 100644 --- a/platform/ios/platform/ios/src/MGLScaleBar.h +++ b/platform/ios/platform/ios/src/MGLScaleBar.h @@ -6,4 +6,10 @@ // Sets the scale and redraws the scale bar @property (nonatomic, assign) CLLocationDistance metersPerPoint; +// Sets whether the scale uses styles that make it easier to read on a dark styled map +@property (nonatomic, assign) BOOL shouldShowDarkStyles; + +// Sets whether the scale uses metric +@property (nonatomic, assign) BOOL usesMetricSystem; + @end diff --git a/platform/ios/platform/ios/src/MGLScaleBar.mm b/platform/ios/platform/ios/src/MGLScaleBar.mm index 3efa80013..f5aed5fd8 100644 --- a/platform/ios/platform/ios/src/MGLScaleBar.mm +++ b/platform/ios/platform/ios/src/MGLScaleBar.mm @@ -98,11 +98,22 @@ static const CGFloat MGLScaleBarLabelWidthHint = 30.0; static const CGFloat MGLScaleBarMinimumBarWidth = 30.0; // Arbitrary @interface MGLScaleBarLabel : UILabel - +@property (nonatomic) BOOL shouldShowDarkStyles; @end @implementation MGLScaleBarLabel +- (void)setShouldShowDarkStyles:(BOOL)shouldShowDarkStyles { + + if (_shouldShowDarkStyles != shouldShowDarkStyles) { + _shouldShowDarkStyles = shouldShowDarkStyles; + + // Redraw labels + [self setNeedsDisplay]; + + } +} + - (void)drawTextInRect:(CGRect)rect { CGSize shadowOffset = self.shadowOffset; @@ -111,11 +122,19 @@ static const CGFloat MGLScaleBarMinimumBarWidth = 30.0; // Arbitrary CGContextSetLineJoin(context, kCGLineJoinRound); CGContextSetTextDrawingMode(context, kCGTextStroke); - self.textColor = [UIColor whiteColor]; + if (_shouldShowDarkStyles) { + self.textColor = [UIColor blackColor]; + } else { + self.textColor = [UIColor whiteColor]; + } [super drawTextInRect:rect]; CGContextSetTextDrawingMode(context, kCGTextFill); - self.textColor = [UIColor blackColor]; + if (self.shouldShowDarkStyles) { + self.textColor = [UIColor whiteColor]; + } else { + self.textColor = [UIColor blackColor]; + } self.shadowOffset = CGSizeMake(0, 0); [super drawTextInRect:rect]; @@ -150,6 +169,10 @@ static const CGFloat MGLScaleBarMinimumBarWidth = 30.0; // Arbitrary self.clipsToBounds = NO; self.hidden = YES; + // Default to current local + NSLocale *locale = [NSLocale currentLocale]; + _usesMetricSystem = [[locale objectForKey:NSLocaleUsesMetricSystem] boolValue]; + _containerView = [[UIView alloc] init]; _containerView.clipsToBounds = YES; _containerView.backgroundColor = _secondaryColor; @@ -168,6 +191,7 @@ static const CGFloat MGLScaleBarMinimumBarWidth = 30.0; // Arbitrary _prototypeLabel = [[MGLScaleBarLabel alloc] init]; _prototypeLabel.font = [UIFont systemFontOfSize:8 weight:UIFontWeightMedium]; _prototypeLabel.clipsToBounds = NO; + _prototypeLabel.shouldShowDarkStyles = _shouldShowDarkStyles; NSUInteger numberOfLabels = 4; NSMutableArray *labelViews = [NSMutableArray arrayWithCapacity:numberOfLabels]; @@ -246,11 +270,6 @@ static const CGFloat MGLScaleBarMinimumBarWidth = 30.0; // Arbitrary return [UIView userInterfaceLayoutDirectionForSemanticContentAttribute:self.superview.semanticContentAttribute] == UIUserInterfaceLayoutDirectionRightToLeft; } -- (BOOL)usesMetricSystem { - NSLocale *locale = [NSLocale currentLocale]; - return [[locale objectForKey:NSLocaleUsesMetricSystem] boolValue]; -} - - (MGLRow)preferredRow { CLLocationDistance maximumDistance = [self maximumWidth] * [self unitsPerPoint]; @@ -282,8 +301,44 @@ static const CGFloat MGLScaleBarMinimumBarWidth = 30.0; // Arbitrary return *table; } + +#pragma mark - Dark Mode Changes + +- (void)setShouldShowDarkStyles:(BOOL)shouldShowDarkStyles { + + if (_shouldShowDarkStyles != shouldShowDarkStyles) { + _shouldShowDarkStyles = shouldShowDarkStyles; + + // Redraw labels + _prototypeLabel.shouldShowDarkStyles = shouldShowDarkStyles; + [self resetLabelImageCache]; + [self updateLabels]; + + } +} + + #pragma mark - Setters +- (void)setUsesMetricSystem:(BOOL)usesMetricSystem { + + if (_usesMetricSystem != usesMetricSystem) { + + _usesMetricSystem = usesMetricSystem; + + // Set the distance formatter locale using Germany for metric and United States for imperial. + self.formatter.numberFormatter.locale = usesMetricSystem ? [NSLocale localeWithLocaleIdentifier:@"de_DE"] : [NSLocale localeWithLocaleIdentifier:@"en_US"]; + + [self resetLabelImageCache]; + [self updateVisibility]; + + self.recalculateSize = YES; + [self invalidateIntrinsicContentSize]; + + } + +} + - (void)setMetersPerPoint:(CLLocationDistance)metersPerPoint { if (_metersPerPoint == metersPerPoint) { return;