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

[ios] Add MGLMapView.showsScale to control scale bar visibility #11335

Merged
merged 2 commits into from
Mar 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions platform/ios/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* Long-pressing the attribution button causes the SDK’s version number to be displayed in the action sheet that appears. ([#10650](https://github.com/mapbox/mapbox-gl-native/pull/10650))
* Reduced offline download size for styles with symbol layers that render only icons, and no text. ([#11055](https://github.com/mapbox/mapbox-gl-native/pull/11055))
* Added haptic feedback that occurs when the user rotates the map to due north, configurable via `MGLMapView.hapticFeedbackEnabled`. ([#10847](https://github.com/mapbox/mapbox-gl-native/pull/10847))
* Added `MGLMapView.showsScale` as the recommended way to show the scale bar. This property can be set directly in Interface Builder. ([#11335](https://github.com/mapbox/mapbox-gl-native/pull/11335))
* Fixed an issue where the scale bar would not appear until the map had moved. ([#11335](https://github.com/mapbox/mapbox-gl-native/pull/11335))

## 3.7.5 - February 16, 2018

Expand Down
2 changes: 1 addition & 1 deletion platform/ios/app/MBXViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ - (void)viewDidLoad
[self restoreState:nil];

self.debugLoggingEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"MGLMapboxMetricsDebugLoggingEnabled"];
self.mapView.scaleBar.hidden = NO;
self.mapView.showsScale = YES;
self.mapView.showsUserHeadingIndicator = YES;
if ([UIFont respondsToSelector:@selector(monospacedDigitSystemFontOfSize:weight:)]) {
self.hudLabel.titleLabel.font = [UIFont monospacedDigitSystemFontOfSize:10 weight:UIFontWeightRegular];
Expand Down
10 changes: 7 additions & 3 deletions platform/ios/ios.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@
9620BB3B1E69FE1700705A1D /* MGLSDKUpdateChecker.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9620BB371E69FE1700705A1D /* MGLSDKUpdateChecker.mm */; };
9654C1261FFC1AB900DB6A19 /* MGLPolyline_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 9654C1251FFC1AB900DB6A19 /* MGLPolyline_Private.h */; };
9654C1291FFC1CCD00DB6A19 /* MGLPolygon_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 9654C1271FFC1CC000DB6A19 /* MGLPolygon_Private.h */; };
9658C155204761FC00D8A674 /* MGLMapViewScaleBarTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9658C154204761FC00D8A674 /* MGLMapViewScaleBarTests.m */; };
966FCF4C1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 966FCF4A1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.h */; };
966FCF4E1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 966FCF4B1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.m */; };
966FCF4F1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 966FCF4B1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.m */; };
Expand Down Expand Up @@ -952,6 +953,7 @@
9620BB371E69FE1700705A1D /* MGLSDKUpdateChecker.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = MGLSDKUpdateChecker.mm; sourceTree = "<group>"; };
9654C1251FFC1AB900DB6A19 /* MGLPolyline_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLPolyline_Private.h; sourceTree = "<group>"; };
9654C1271FFC1CC000DB6A19 /* MGLPolygon_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLPolygon_Private.h; sourceTree = "<group>"; };
9658C154204761FC00D8A674 /* MGLMapViewScaleBarTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLMapViewScaleBarTests.m; sourceTree = "<group>"; };
9660916B1E5BBFD700A9A03B /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
9660916C1E5BBFD900A9A03B /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = "<group>"; };
9660916D1E5BBFDB00A9A03B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1773,24 +1775,25 @@
4031ACFD1E9FD26900A3EA26 /* Test Helpers */,
409F43FB1E9E77D10048729D /* Swift Integration */,
357579811D502AD4000B822E /* Styling */,
DAEDC4331D603417000224FF /* MGLAttributionInfoTests.m */,
353D23951D0B0DFE002BE09D /* MGLAnnotationViewTests.m */,
DAEDC4331D603417000224FF /* MGLAttributionInfoTests.m */,
DA35A2C31CCA9F8300E826B2 /* MGLClockDirectionFormatterTests.m */,
35D9DDE11DA25EEC00DAAD69 /* MGLCodingTests.m */,
DA35A2C41CCA9F8300E826B2 /* MGLCompassDirectionFormatterTests.m */,
DA35A2A91CCA058D00E826B2 /* MGLCoordinateFormatterTests.m */,
3598544C1E1D38AA00B29F84 /* MGLDistanceFormatterTests.m */,
6407D66F1E0085FD00F6A9C3 /* MGLDocumentationExampleTests.swift */,
DA1F8F3C1EBD287B00367E42 /* MGLDocumentationGuideTests.swift */,
DD58A4C51D822BD000E1F038 /* MGLExpressionTests.mm */,
3598544C1E1D38AA00B29F84 /* MGLDistanceFormatterTests.m */,
DA0CD58F1CF56F6A00A5F5A5 /* MGLFeatureTests.mm */,
DA2E885C1CC0382C00F24E7B /* MGLGeometryTests.mm */,
DA5DB1291FABF1EE001C2326 /* MGLMapAccessibilityElementTests.m */,
16376B481FFEED010000563E /* MGLMapViewLayoutTests.m */,
9658C154204761FC00D8A674 /* MGLMapViewScaleBarTests.m */,
35E208A61D24210F00EC9A46 /* MGLNSDataAdditionsTests.m */,
1F95931C1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm */,
DAE7DEC11E245455007505A6 /* MGLNSStringAdditionsTests.m */,
96036A0520059BBA00510F3D /* MGLNSOrthographyAdditionsTests.m */,
DAE7DEC11E245455007505A6 /* MGLNSStringAdditionsTests.m */,
DA2E885D1CC0382C00F24E7B /* MGLOfflinePackTests.m */,
DA2E885E1CC0382C00F24E7B /* MGLOfflineRegionTests.m */,
55E2AD121E5B125400E8C587 /* MGLOfflineStorageTests.mm */,
Expand Down Expand Up @@ -2827,6 +2830,7 @@
1F95931D1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm in Sources */,
DD58A4C61D822BD000E1F038 /* MGLExpressionTests.mm in Sources */,
3575798B1D502B0C000B822E /* MGLBackgroundStyleLayerTests.mm in Sources */,
9658C155204761FC00D8A674 /* MGLMapViewScaleBarTests.m in Sources */,
409D0A0D1ED614CE00C95D0C /* MGLAnnotationViewIntegrationTests.swift in Sources */,
DA2E88621CC0382C00F24E7B /* MGLOfflinePackTests.m in Sources */,
55E2AD131E5B125400E8C587 /* MGLOfflineStorageTests.mm in Sources */,
Expand Down
1 change: 1 addition & 0 deletions platform/ios/src/MGLMapView+IBAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic) IBInspectable BOOL allowsTilting;
@property (nonatomic) IBInspectable BOOL showsUserLocation;
@property (nonatomic) IBInspectable BOOL showsHeading;
@property (nonatomic) IBInspectable BOOL showsScale;

@end

Expand Down
11 changes: 10 additions & 1 deletion platform/ios/src/MGLMapView.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,18 @@ MGL_EXPORT IB_DESIGNABLE
*/
- (IBAction)reloadStyle:(id)sender;

/**
A Boolean value indicating whether the map may display scale information.

The scale bar may not be shown at all zoom levels. The view controlled by this
property is available at `scaleBar`. The default value of this property is
`NO`.
*/
@property (nonatomic, assign) BOOL showsScale;

/**
A control indicating the scale of the map. The scale bar is positioned in the
upper-left corner. The scale bar is hidden by default.
upper-left corner. Enable the scale bar via `showsScale`.
*/
@property (nonatomic, readonly) UIView *scaleBar;

Expand Down
32 changes: 26 additions & 6 deletions platform/ios/src/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -975,8 +975,8 @@ - (void)glkView:(__unused GLKView *)view drawInRect:(__unused CGRect)rect
- (void)layoutSubviews
{
// Calling this here instead of in the scale bar itself because if this is done in the
// scale bar instance, it triggers a call to this this `layoutSubviews` method that
// calls `_mbglMap->setSize()` just below that triggers rendering update which triggers
// scale bar instance, it triggers a call to this `layoutSubviews` method that calls
// `_mbglMap->setSize()` just below that triggers rendering update which triggers
// another scale bar update which causes a rendering update loop and a major performace
// degradation. The only time the scale bar's intrinsic content size _must_ invalidated
// is here as a reaction to this object's view dimension changes.
Expand Down Expand Up @@ -2362,6 +2362,17 @@ - (void)setPitchEnabled:(BOOL)pitchEnabled
self.twoFingerDrag.enabled = pitchEnabled;
}

- (void)setShowsScale:(BOOL)showsScale
{
_showsScale = showsScale;
self.scaleBar.hidden = !showsScale;

if (showsScale)
{
[self updateScaleBar];
}
}

#pragma mark - Accessibility -

- (NSString *)accessibilityValue
Expand Down Expand Up @@ -5413,10 +5424,7 @@ - (void)cameraIsChanging {
}

[self updateCompass];

if (!self.scaleBar.hidden) {
[(MGLScaleBar *)self.scaleBar setMetersPerPoint:[self metersPerPointAtLatitude:self.centerCoordinate.latitude]];
}
[self updateScaleBar];

if ([self.delegate respondsToSelector:@selector(mapView:regionIsChangingWithReason:)])
{
Expand All @@ -5434,6 +5442,7 @@ - (void)cameraDidChangeAnimated:(BOOL)animated {
}

[self updateCompass];
[self updateScaleBar];

if ( ! [self isSuppressingChangeDelimiters])
{
Expand Down Expand Up @@ -5878,6 +5887,17 @@ - (void)updateCompass
}
}

- (void)updateScaleBar
{
// Use the `hidden` property (instead of `self.showsScale`) so that we don't
// break developers who still rely on the <4.0.0 approach of directly
// setting this property.
if ( ! self.scaleBar.hidden)
{
[(MGLScaleBar *)self.scaleBar setMetersPerPoint:[self metersPerPointAtLatitude:self.centerCoordinate.latitude]];
}
}

+ (UIImage *)resourceImageNamed:(NSString *)imageName
{
UIImage *image = [UIImage imageNamed:imageName
Expand Down
5 changes: 3 additions & 2 deletions platform/ios/test/MGLMapViewLayoutTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,15 @@ - (void)setUp {
self.styleLoadingExpectation = [self expectationWithDescription:@"Map view should finish loading style."];
[self waitForExpectationsWithTimeout:1 handler:nil];

self.mapView.showsScale = YES;

//set zoom and heading so that scale bar and compass will be shown
[self.mapView setZoomLevel:4.5 animated:NO];
[self.mapView setZoomLevel:10.0 animated:NO];
[self.mapView.camera setHeading:12.0];

//invoke layout
[self.superView setNeedsLayout];
[self.superView layoutIfNeeded];

}

- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
Expand Down
62 changes: 62 additions & 0 deletions platform/ios/test/MGLMapViewScaleBarTests.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#import <Mapbox/Mapbox.h>
#import <XCTest/XCTest.h>

@interface MGLMapViewScaleBarTests : XCTestCase

@property (nonatomic) MGLMapView *mapView;

@end

@implementation MGLMapViewScaleBarTests

- (void)setUp {
[super setUp];

[MGLAccountManager setAccessToken:@"pk.feedcafedeadbeefbadebede"];
NSURL *styleURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"one-liner" withExtension:@"json"];
self.mapView = [[MGLMapView alloc] initWithFrame:UIScreen.mainScreen.bounds styleURL:styleURL];
}

- (void)tearDown {
self.mapView = nil;

[super tearDown];
}

- (void)testShowsScale {
UIView *scaleBar = self.mapView.scaleBar;

// Scale bar should not be enabled by default.
XCTAssertFalse(self.mapView.showsScale);
XCTAssertTrue(scaleBar.hidden);

self.mapView.showsScale = YES;

XCTAssertFalse(scaleBar.hidden);

// Scale bar should not be visible at default zoom (~z0), but it should be ready.
XCTAssertFalse(CGRectIsEmpty(scaleBar.frame));
XCTAssertEqual(scaleBar.alpha, 0);

self.mapView.zoomLevel = 15;
XCTAssertGreaterThan(scaleBar.alpha, 0);
}

- (void)testDirectlySettingScaleBarViewHiddenProperty {
UIView *scaleBar = self.mapView.scaleBar;

scaleBar.hidden = NO;
XCTAssertFalse(scaleBar.hidden);

// Directly setting `.hidden` after the map has finished initializing will not update the scale bar.
XCTAssertTrue(CGRectIsEmpty(scaleBar.frame));

// ... but triggering any camera event will update it.
self.mapView.zoomLevel = 1;
XCTAssertFalse(CGRectIsEmpty(scaleBar.frame));
XCTAssertEqual(scaleBar.alpha, 0);

self.mapView.zoomLevel = 15;
XCTAssertGreaterThan(scaleBar.alpha, 0);
}
@end