[core, ios] Call transitionFinishFn for jumpTo. (#15473)

This commit is contained in:
Julian Rex
2019-09-05 00:21:58 -04:00
committed by GitHub
parent fa3bf5855b
commit 96581fd3ff
8 changed files with 151 additions and 16 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -42,4 +42,5 @@
- (NSString*)validAccessToken;
- (void)waitForMapViewToFinishLoadingStyleWithTimeout:(NSTimeInterval)timeout;
- (void)waitForMapViewToBeRenderedWithTimeout:(NSTimeInterval)timeout;
- (MGLMapView *)mapViewForTestWithFrame:(CGRect)rect styleURL:(NSURL *)styleURL;
@end

View File

@@ -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];

View File

@@ -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) {

View File

@@ -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;
};

View File

@@ -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;
}