From 97840a684a1001c2046493dd4b7a110bb80fc9f5 Mon Sep 17 00:00:00 2001 From: Julian Rex Date: Mon, 12 Oct 2020 13:00:21 -0400 Subject: [PATCH] Add compass image as a sublayer (#501) --- circle.yml | 4 ++-- platform/ios/CHANGELOG.md | 11 ++++++--- platform/ios/src/MGLCompassButton.mm | 24 +++++++++++++++---- platform/ios/src/MGLCompassButton_Private.h | 1 + platform/ios/src/MGLMapView.mm | 5 +++- .../ios/test/MGLMapViewCompassViewTests.mm | 19 ++++++++++----- 6 files changed, 48 insertions(+), 16 deletions(-) diff --git a/circle.yml b/circle.yml index 46104c1dd9..9254c614d5 100644 --- a/circle.yml +++ b/circle.yml @@ -19,7 +19,7 @@ workflows: - ios-build: matrix: parameters: - xcode: ["11.1.0", "11.7.0"] + xcode: ["11.7.0", "12.0.0"] buildtype: ["Debug", "Release"] - ios-release-template: xcode: "12.0.0" @@ -57,7 +57,7 @@ workflows: - ios-build: matrix: parameters: - xcode: ["11.3.1", "11.5.0", "11.6.0", "12.0.0"] + xcode: ["11.1.0", "11.3.1", "12.2.0"] buildtype: ["Debug", "Release"] - ios-sanitize-nightly: requires: diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 3e59d5349d..612a646bca 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -4,14 +4,19 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT ## 6.3.0 +### 🐞 Bug fixes + +* Partly fixed an issue on iOS 14 where `-[UIView layoutSubviews]` was being repeatedly called. ([#501](https://github.com/mapbox/mapbox-gl-native-ios/pull/501)) +* Fixed a bug with UIViews being incorrectly updated with a one frame delay. ([#483](https://github.com/mapbox/mapbox-gl-native-ios/pull/483)) +* Fixed an issue where CocoaPods users could not install the SDK when using Xcode 12. ([#482](https://github.com/mapbox/mapbox-gl-native-ios/pull/482)) + ### 🔧 Dependencies * Updated `mapbox-events-ios` to `0.10.5-beta.2` in order to add additional iOS 14 support.([#491](https://github.com/mapbox/mapbox-gl-native-ios/pull/491)) -### 🐞 Bug fixes +### ✨ Other changes -* Fixed a bug with UIViews being incorrectly updated with a one frame delay. ([#483](https://github.com/mapbox/mapbox-gl-native-ios/pull/483)) -* Fixed an issue where CocoaPods users could not install the SDK when using Xcode 12. ([#482](https://github.com/mapbox/mapbox-gl-native-ios/pull/482)) +* The default branch is now `main`. Please rebase any existing branches you may have. ([#489](https://github.com/mapbox/mapbox-gl-native-ios/pull/489)) ## 6.2.1 - September 23, 2020 diff --git a/platform/ios/src/MGLCompassButton.mm b/platform/ios/src/MGLCompassButton.mm index 5bbd9bf923..4d476247e6 100644 --- a/platform/ios/src/MGLCompassButton.mm +++ b/platform/ios/src/MGLCompassButton.mm @@ -12,6 +12,7 @@ @interface MGLCompassButton () @property (nonatomic, weak) MGLMapView *mapView; +@property (nonatomic) CALayer *imageLayer; @property (nonatomic) MGLCompassDirectionFormatter *accessibilityCompassFormatter; @end @@ -30,8 +31,21 @@ - (instancetype)initWithMapView:(MGLMapView *)mapView { return self; } +- (void)setImage:(UIImage *)image { + self.imageLayer.contents = (id)image.CGImage; +} + - (void)commonInit { - self.image = self.compassImage; + UIImage *image = self.compassImage; + CGRect bounds = (CGRect){CGPointZero, image.size}; + self.bounds = bounds; + + self.imageLayer = [[CALayer alloc] init]; + self.imageLayer.frame = bounds; + self.imageLayer.contentsGravity = kCAGravityResizeAspect; + + self.image = image; + [self.layer addSublayer:self.imageLayer]; self.compassVisibility = MGLOrnamentVisibilityAdaptive; @@ -48,8 +62,6 @@ - (void)commonInit { self.accessibilityCompassFormatter = [[MGLCompassDirectionFormatter alloc] init]; self.accessibilityCompassFormatter.unitStyle = NSFormattingUnitStyleLong; - - [self sizeToFit]; } - (void)setCompassVisibility:(MGLOrnamentVisibility)compassVisibility { @@ -96,7 +108,11 @@ - (void)updateCompass { - (void)updateCompassAnimated:(BOOL)animated { CLLocationDirection direction = self.mapView.direction; CLLocationDirection plateDirection = mbgl::util::wrap(-direction, 0., 360.); - self.transform = CGAffineTransformMakeRotation(MGLRadiansFromDegrees(plateDirection)); + + [CATransaction begin]; + [CATransaction setValue:@(YES) forKey:kCATransactionDisableActions]; + self.imageLayer.transform = CATransform3DMakeRotation(MGLRadiansFromDegrees(plateDirection), 0.0, 0.0, 1.0); + [CATransaction commit]; self.isAccessibilityElement = direction > 0; self.accessibilityValue = [self.accessibilityCompassFormatter stringFromDirection:direction]; diff --git a/platform/ios/src/MGLCompassButton_Private.h b/platform/ios/src/MGLCompassButton_Private.h index 9ef55cfa5b..9f76c558e0 100644 --- a/platform/ios/src/MGLCompassButton_Private.h +++ b/platform/ios/src/MGLCompassButton_Private.h @@ -11,6 +11,7 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)compassButtonWithMapView:(MGLMapView *)mapView; @property (nonatomic, weak) MGLMapView *mapView; +@property (nonatomic) CALayer *imageLayer; - (void)updateCompass; diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 820f56404b..0f6300092e 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -7269,7 +7269,10 @@ - (CGPoint)userLocationAnnotationViewCenter - (void)updateCompass { - [self.compassView updateCompass]; + if ((self.compassView.compassVisibility != MGLOrnamentVisibilityHidden) && + (!self.compassView.isHidden)) { + [self.compassView updateCompass]; + } } - (void)updateScaleBar diff --git a/platform/ios/test/MGLMapViewCompassViewTests.mm b/platform/ios/test/MGLMapViewCompassViewTests.mm index aaec4b0bf7..2c3445417a 100644 --- a/platform/ios/test/MGLMapViewCompassViewTests.mm +++ b/platform/ios/test/MGLMapViewCompassViewTests.mm @@ -1,6 +1,6 @@ #import #import - +#import "MGLCompassButton_Private.h" #import @interface MGLMapView (MGLCompassButtonTests) @@ -84,14 +84,21 @@ - (void)testCompassRotation { for (NSNumber *degrees in @[@-999, @-359, @-240, @-180, @-90, @-45, @0, @45, @90, @180, @240, @360, @999]) { self.mapView.direction = [degrees doubleValue]; CGFloat wrappedDirection = mbgl::util::wrap(-self.mapView.direction, 0., 360.); - CGAffineTransform rotation = CGAffineTransformMakeRotation(MGLRadiansFromDegrees(wrappedDirection)); - XCTAssertTrue(CGAffineTransformEqualToTransform(self.mapView.compassView.transform, rotation), - @"Compass transform direction %f° should equal wrapped transform direction %f° (~%.f°).", [self degreesFromAffineTransform:self.mapView.compassView.transform], [self degreesFromAffineTransform:rotation], wrappedDirection); + CATransform3D rotation = CATransform3DMakeRotation(MGLRadiansFromDegrees(wrappedDirection), 0.0, 0.0, 1.0); + + CGFloat deg1 = [self degreesFromAffineTransform:self.mapView.compassView.imageLayer.transform]; + CGFloat deg2 = [self degreesFromAffineTransform:rotation]; + XCTAssertEqual(deg1, deg2); + XCTAssertTrue(CATransform3DEqualToTransform(self.mapView.compassView.imageLayer.transform, rotation), + @"Compass transform direction %f° should equal wrapped transform direction %f° (~%.f°).", + deg1, + deg2, + wrappedDirection); } } -- (CGFloat)degreesFromAffineTransform:(CGAffineTransform)transform { - CGFloat angle = atan2f(transform.b, transform.a); +- (CGFloat)degreesFromAffineTransform:(CATransform3D)transform { + CGFloat angle = atan2f(transform.m12, transform.m11); return MGLDegreesFromRadians(angle); }