diff options
-rw-r--r-- | platform/ios/CHANGELOG.md | 1 | ||||
-rw-r--r-- | platform/ios/Integration Tests/Camera Tests/MGLCameraTransitionFinishTests.mm | 109 | ||||
-rw-r--r-- | platform/ios/Integration Tests/Camera Tests/MGLCameraTransitionTests.mm (renamed from platform/ios/Integration Tests/MGLCameraTransitionTests.mm) | 18 | ||||
-rw-r--r-- | platform/ios/Integration Tests/MGLMapViewIntegrationTest.h | 1 | ||||
-rw-r--r-- | platform/ios/Integration Tests/MGLMapViewIntegrationTest.m | 6 | ||||
-rw-r--r-- | platform/ios/Integration Tests/MGLMapViewPendingBlockTests.m | 3 | ||||
-rw-r--r-- | platform/ios/ios.xcodeproj/project.pbxproj | 20 | ||||
-rw-r--r-- | src/mbgl/map/transform.cpp | 9 |
8 files changed, 151 insertions, 16 deletions
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index bdf855aa3c..2132be5077 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -10,6 +10,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Fixed an issue where the scale bar text would become illegible if iOS 13 dark mode was enabled. ([#15524](https://github.com/mapbox/mapbox-gl-native/pull/15524)) * Enabled use of `MGLSymbolStyleLayer.textOffset` option together with `MGLSymbolStyleLayer.textVariableAnchor` (if `MGLSymbolStyleLayer.textRadialOffset` option is not provided). ([#15542](https://github.com/mapbox/mapbox-gl-native/pull/15542)) * Fixed an issue with the appearance of the compass text in iOS 13. ([#15547](https://github.com/mapbox/mapbox-gl-native/pull/15547)) +* Fixed a bug where the completion block passed to `-[MGLMapView flyToCamera:completionHandler:` (and related methods) wouldn't be called. ([#15473](https://github.com/mapbox/mapbox-gl-native/pull/15473)) ### Performance improvements diff --git a/platform/ios/Integration Tests/Camera Tests/MGLCameraTransitionFinishTests.mm b/platform/ios/Integration Tests/Camera Tests/MGLCameraTransitionFinishTests.mm new file mode 100644 index 0000000000..1527e8dbe5 --- /dev/null +++ b/platform/ios/Integration Tests/Camera Tests/MGLCameraTransitionFinishTests.mm @@ -0,0 +1,109 @@ +#import "MGLMapViewIntegrationTest.h" +#import "MGLTestUtility.h" +#import "../../darwin/src/MGLGeometry_Private.h" + +#include <mbgl/map/camera.hpp> + +@interface MGLCameraTransitionFinishTests : MGLMapViewIntegrationTest +@end + +@implementation MGLCameraTransitionFinishTests + +- (void)testEaseToCompletionHandler { + + MGLCoordinateBounds bounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(0.0, 0.0), + CLLocationCoordinate2DMake(1.0, 1.0)); + MGLMapCamera *camera = [self.mapView cameraThatFitsCoordinateBounds:bounds]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"Completion block should be called"]; + + [self.mapView setCamera:camera + withDuration:0.0 + animationTimingFunction:nil + completionHandler:^{ + [expectation fulfill]; + }]; + + [self waitForExpectations:@[expectation] timeout:0.5]; +} + +- (void)testEaseToCompletionHandlerAnimated { + + MGLCoordinateBounds bounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(0.0, 0.0), + CLLocationCoordinate2DMake(1.0, 1.0)); + MGLMapCamera *camera = [self.mapView cameraThatFitsCoordinateBounds:bounds]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"Completion block should be called"]; + + [self.mapView setCamera:camera + withDuration:0.3 + animationTimingFunction:nil + completionHandler:^{ + [expectation fulfill]; + }]; + + [self waitForExpectations:@[expectation] timeout:0.5]; +} + +- (void)testFlyToCompletionHandler { + + MGLCoordinateBounds bounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(0.0, 0.0), + CLLocationCoordinate2DMake(1.0, 1.0)); + MGLMapCamera *camera = [self.mapView cameraThatFitsCoordinateBounds:bounds]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"Completion block should be called"]; + + [self.mapView flyToCamera:camera + withDuration:0.0 + completionHandler:^{ + [expectation fulfill]; + }]; + + [self waitForExpectations:@[expectation] timeout:0.5]; +} + +- (void)testFlyToCompletionHandlerAnimated { + + MGLCoordinateBounds bounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(0.0, 0.0), + CLLocationCoordinate2DMake(1.0, 1.0)); + MGLMapCamera *camera = [self.mapView cameraThatFitsCoordinateBounds:bounds]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"Completion block should be called"]; + + [self.mapView flyToCamera:camera + withDuration:0.3 + completionHandler:^{ + [expectation fulfill]; + }]; + + [self waitForExpectations:@[expectation] timeout:0.5]; +} +@end + +#pragma mark - camera transitions with NaN values + +@interface MGLMapView (MGLCameraTransitionFinishNaNTests) +- (mbgl::CameraOptions)cameraOptionsObjectForAnimatingToCamera:(MGLMapCamera *)camera edgePadding:(UIEdgeInsets)insets; +@end + +@interface MGLCameraTransitionNaNZoomMapView: MGLMapView +@end + +@implementation MGLCameraTransitionNaNZoomMapView +- (mbgl::CameraOptions)cameraOptionsObjectForAnimatingToCamera:(MGLMapCamera *)camera edgePadding:(UIEdgeInsets)insets { + mbgl::CameraOptions options = [super cameraOptionsObjectForAnimatingToCamera:camera edgePadding:insets]; + options.zoom = NAN; + return options; +} +@end + +// Subclass the entire test suite, but with a different MGLMapView subclass +@interface MGLCameraTransitionFinishNaNTests : MGLCameraTransitionFinishTests +@end + +@implementation MGLCameraTransitionFinishNaNTests +- (MGLMapView *)mapViewForTestWithFrame:(CGRect)rect styleURL:(NSURL *)styleURL { + return [[MGLCameraTransitionNaNZoomMapView alloc] initWithFrame:rect styleURL:styleURL]; +} +@end + diff --git a/platform/ios/Integration Tests/MGLCameraTransitionTests.mm b/platform/ios/Integration Tests/Camera Tests/MGLCameraTransitionTests.mm index 9679c4c11f..2965882372 100644 --- a/platform/ios/Integration Tests/MGLCameraTransitionTests.mm +++ b/platform/ios/Integration Tests/Camera Tests/MGLCameraTransitionTests.mm @@ -2,10 +2,10 @@ #import "MGLTestUtility.h" #import "../../darwin/src/MGLGeometry_Private.h" -@interface MBCameraTransitionTests : MGLMapViewIntegrationTest +@interface MGLCameraTransitionTests : MGLMapViewIntegrationTest @end -@implementation MBCameraTransitionTests +@implementation MGLCameraTransitionTests - (void)testSetAndResetNorthWithDispatchAsyncInDelegateMethod { @@ -17,7 +17,7 @@ self.regionDidChange = ^(MGLMapView *mapView, MGLCameraChangeReason reason, BOOL animated) { - MBCameraTransitionTests *strongSelf = weakself; + MGLCameraTransitionTests *strongSelf = weakself; if (!strongSelf) return; @@ -48,7 +48,7 @@ self.regionDidChange = ^(MGLMapView *mapView, MGLCameraChangeReason reason, BOOL animated) { - MBCameraTransitionTests *strongSelf = weakself; + MGLCameraTransitionTests *strongSelf = weakself; if (!strongSelf) return; @@ -79,7 +79,7 @@ __block BOOL finishedReset = NO; self.regionIsChanging = ^(MGLMapView *mapView) { - MBCameraTransitionTests *strongSelf = weakself; + MGLCameraTransitionTests *strongSelf = weakself; if (!strongSelf) return; if (!startedReset) { @@ -91,7 +91,7 @@ }; self.regionDidChange = ^(MGLMapView *mapView, MGLCameraChangeReason reason, BOOL animated) { - MBCameraTransitionTests *strongSelf = weakself; + MGLCameraTransitionTests *strongSelf = weakself; if (!strongSelf) return; MGLTestAssert(strongSelf, startedReset); @@ -127,7 +127,7 @@ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.15 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ - MBCameraTransitionTests *strongSelf = weakself; + MGLCameraTransitionTests *strongSelf = weakself; [strongSelf.mapView setCenterCoordinate:dc zoomLevel:zoomLevel animated:NO]; MGLTestAssertEqualWithAccuracy(strongSelf, @@ -160,7 +160,7 @@ self.regionDidChange = ^(MGLMapView *mapView, MGLCameraChangeReason reason, BOOL animated) { - MBCameraTransitionTests *strongSelf = weakself; + MGLCameraTransitionTests *strongSelf = weakself; if (!strongSelf) return; @@ -248,7 +248,7 @@ self.regionDidChange = ^(MGLMapView *mapView, MGLCameraChangeReason reason, BOOL animated) { - MBCameraTransitionTests *strongSelf = weakself; + MGLCameraTransitionTests *strongSelf = weakself; if (!strongSelf) return; diff --git a/platform/ios/Integration Tests/MGLMapViewIntegrationTest.h b/platform/ios/Integration Tests/MGLMapViewIntegrationTest.h index 07d8698f38..9cebb08ab6 100644 --- a/platform/ios/Integration Tests/MGLMapViewIntegrationTest.h +++ b/platform/ios/Integration Tests/MGLMapViewIntegrationTest.h @@ -42,4 +42,5 @@ - (NSString*)validAccessToken; - (void)waitForMapViewToFinishLoadingStyleWithTimeout:(NSTimeInterval)timeout; - (void)waitForMapViewToBeRenderedWithTimeout:(NSTimeInterval)timeout; +- (MGLMapView *)mapViewForTestWithFrame:(CGRect)rect styleURL:(NSURL *)styleURL; @end diff --git a/platform/ios/Integration Tests/MGLMapViewIntegrationTest.m b/platform/ios/Integration Tests/MGLMapViewIntegrationTest.m index 3fa191dfcd..1538c09516 100644 --- a/platform/ios/Integration Tests/MGLMapViewIntegrationTest.m +++ b/platform/ios/Integration Tests/MGLMapViewIntegrationTest.m @@ -33,13 +33,17 @@ return accessToken; } +- (MGLMapView *)mapViewForTestWithFrame:(CGRect)rect styleURL:(NSURL *)styleURL { + return [[MGLMapView alloc] initWithFrame:UIScreen.mainScreen.bounds styleURL:styleURL]; +} + - (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]; + self.mapView = [self mapViewForTestWithFrame:UIScreen.mainScreen.bounds styleURL:styleURL]; self.mapView.delegate = self; UIView *superView = [[UIView alloc] initWithFrame:UIScreen.mainScreen.bounds]; diff --git a/platform/ios/Integration Tests/MGLMapViewPendingBlockTests.m b/platform/ios/Integration Tests/MGLMapViewPendingBlockTests.m index ad71dafd48..c7925d7896 100644 --- a/platform/ios/Integration Tests/MGLMapViewPendingBlockTests.m +++ b/platform/ios/Integration Tests/MGLMapViewPendingBlockTests.m @@ -149,8 +149,7 @@ addToPendingCallback:nil]; } -// Marked as pending due to https://github.com/mapbox/mapbox-gl-native/issues/15471 -- (void)testFlyToCameraPENDING { +- (void)testFlyToCamera { __typeof__(self) weakSelf = self; void (^transition)(dispatch_block_t) = ^(dispatch_block_t completion) { diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index 018a5f9368..f7d5b35e08 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -506,9 +506,10 @@ CA0C27922076C804001CE5B7 /* MGLShapeSourceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CA0C27912076C804001CE5B7 /* MGLShapeSourceTests.m */; }; CA0C27942076CA19001CE5B7 /* MGLMapViewIntegrationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CA0C27932076CA19001CE5B7 /* MGLMapViewIntegrationTest.m */; }; CA1B4A512099FB2200EDD491 /* MGLMapSnapshotterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CA1B4A502099FB2200EDD491 /* MGLMapSnapshotterTest.m */; }; - CA34C9C3207FD272005C1A06 /* MGLCameraTransitionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA34C9C2207FD272005C1A06 /* MGLCameraTransitionTests.mm */; }; CA4EB8C720863487006AB465 /* MGLStyleLayerIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CA4EB8C620863487006AB465 /* MGLStyleLayerIntegrationTests.m */; }; CA4F3BDE230F74C3008BAFEA /* MGLMapViewPendingBlockTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CA4F3BDD230F74C3008BAFEA /* MGLMapViewPendingBlockTests.m */; }; + CA4F3BE223107793008BAFEA /* MGLCameraTransitionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA4F3BE123107793008BAFEA /* MGLCameraTransitionTests.mm */; }; + CA4F3BE4231077B9008BAFEA /* MGLCameraTransitionFinishTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA4F3BE3231077B9008BAFEA /* MGLCameraTransitionFinishTests.mm */; }; CA55CD41202C16AA00CE7095 /* MGLCameraChangeReason.h in Headers */ = {isa = PBXBuildFile; fileRef = CA55CD3E202C16AA00CE7095 /* MGLCameraChangeReason.h */; settings = {ATTRIBUTES = (Public, ); }; }; CA55CD42202C16AA00CE7095 /* MGLCameraChangeReason.h in Headers */ = {isa = PBXBuildFile; fileRef = CA55CD3E202C16AA00CE7095 /* MGLCameraChangeReason.h */; settings = {ATTRIBUTES = (Public, ); }; }; CA65C4F821E9BB080068B0D4 /* MGLCluster.h in Headers */ = {isa = PBXBuildFile; fileRef = CA65C4F721E9BB080068B0D4 /* MGLCluster.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1197,9 +1198,10 @@ CA0C27932076CA19001CE5B7 /* MGLMapViewIntegrationTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLMapViewIntegrationTest.m; sourceTree = "<group>"; wrapsLines = 0; }; CA0C27952076CA50001CE5B7 /* MGLMapViewIntegrationTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLMapViewIntegrationTest.h; sourceTree = "<group>"; }; CA1B4A502099FB2200EDD491 /* MGLMapSnapshotterTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLMapSnapshotterTest.m; sourceTree = "<group>"; }; - CA34C9C2207FD272005C1A06 /* MGLCameraTransitionTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLCameraTransitionTests.mm; sourceTree = "<group>"; }; CA4EB8C620863487006AB465 /* MGLStyleLayerIntegrationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLStyleLayerIntegrationTests.m; sourceTree = "<group>"; }; CA4F3BDD230F74C3008BAFEA /* MGLMapViewPendingBlockTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLMapViewPendingBlockTests.m; sourceTree = "<group>"; }; + CA4F3BE123107793008BAFEA /* MGLCameraTransitionTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLCameraTransitionTests.mm; sourceTree = "<group>"; }; + CA4F3BE3231077B9008BAFEA /* MGLCameraTransitionFinishTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLCameraTransitionFinishTests.mm; sourceTree = "<group>"; }; CA55CD3E202C16AA00CE7095 /* MGLCameraChangeReason.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLCameraChangeReason.h; sourceTree = "<group>"; }; CA5E5042209BDC5F001A8A81 /* MGLTestUtility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MGLTestUtility.h; path = ../../darwin/test/MGLTestUtility.h; sourceTree = "<group>"; }; CA65C4F721E9BB080068B0D4 /* MGLCluster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLCluster.h; sourceTree = "<group>"; }; @@ -1543,12 +1545,12 @@ 16376B081FFD9DAF0000563E /* Integration Tests */ = { isa = PBXGroup; children = ( + CA4F3BE023107793008BAFEA /* Camera Tests */, CA6914B320E67F07002DB0EE /* Annotations */, CAE7AD5320F46EF5003B6782 /* integration-Bridging-Header.h */, CA1B4A4F2099FA2800EDD491 /* Snapshotter Tests */, 16376B091FFD9DAF0000563E /* MBGLIntegrationTests.mm */, 16376B0B1FFD9DAF0000563E /* Info.plist */, - CA34C9C2207FD272005C1A06 /* MGLCameraTransitionTests.mm */, CA0C27912076C804001CE5B7 /* MGLShapeSourceTests.m */, CA0C27932076CA19001CE5B7 /* MGLMapViewIntegrationTest.m */, CA0C27952076CA50001CE5B7 /* MGLMapViewIntegrationTest.h */, @@ -1926,6 +1928,15 @@ path = "Snapshotter Tests"; sourceTree = "<group>"; }; + CA4F3BE023107793008BAFEA /* Camera Tests */ = { + isa = PBXGroup; + children = ( + CA4F3BE123107793008BAFEA /* MGLCameraTransitionTests.mm */, + CA4F3BE3231077B9008BAFEA /* MGLCameraTransitionFinishTests.mm */, + ); + path = "Camera Tests"; + sourceTree = "<group>"; + }; CA6914B320E67F07002DB0EE /* Annotations */ = { isa = PBXGroup; children = ( @@ -3197,7 +3208,6 @@ files = ( CA4EB8C720863487006AB465 /* MGLStyleLayerIntegrationTests.m in Sources */, CA7766842229C11A0008DE9E /* SMCalloutView.m in Sources */, - CA34C9C3207FD272005C1A06 /* MGLCameraTransitionTests.mm in Sources */, 16376B0A1FFD9DAF0000563E /* MBGLIntegrationTests.mm in Sources */, CA4F3BDE230F74C3008BAFEA /* MGLMapViewPendingBlockTests.m in Sources */, CA88DC3021C85D900059ED5A /* MGLStyleURLIntegrationTest.m in Sources */, @@ -3207,7 +3217,9 @@ CA0C27922076C804001CE5B7 /* MGLShapeSourceTests.m in Sources */, 077061DA215DA00E000FEF62 /* MGLTestLocationManager.m in Sources */, CA6914B520E67F50002DB0EE /* MGLAnnotationViewIntegrationTests.mm in Sources */, + CA4F3BE223107793008BAFEA /* MGLCameraTransitionTests.mm in Sources */, CA1B4A512099FB2200EDD491 /* MGLMapSnapshotterTest.m in Sources */, + CA4F3BE4231077B9008BAFEA /* MGLCameraTransitionFinishTests.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp index 925893b2d6..7ec41be37a 100644 --- a/src/mbgl/map/transform.cpp +++ b/src/mbgl/map/transform.cpp @@ -96,6 +96,9 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim double pitch = camera.pitch ? *camera.pitch * util::DEG2RAD : getPitch(); if (std::isnan(zoom) || std::isnan(bearing) || std::isnan(pitch)) { + if (animation.transitionFinishFn) { + animation.transitionFinishFn(); + } return; } @@ -172,6 +175,9 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima double pitch = camera.pitch ? *camera.pitch * util::DEG2RAD : getPitch(); if (std::isnan(zoom) || std::isnan(bearing) || std::isnan(pitch) || state.size.isEmpty()) { + if (animation.transitionFinishFn) { + animation.transitionFinishFn(); + } return; } @@ -274,6 +280,9 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima if (duration == Duration::zero()) { // Perform an instantaneous transition. jumpTo(camera); + if (animation.transitionFinishFn) { + animation.transitionFinishFn(); + } return; } |