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

Add completion handlers to animated MGLMapView methods #14381

Merged
merged 3 commits into from
Jun 22, 2019
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
117 changes: 114 additions & 3 deletions platform/darwin/test/MGLMapViewTests.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
#import <Mapbox/Mapbox.h>
#import <XCTest/XCTest.h>
#import <TargetConditionals.h>

#if TARGET_OS_IPHONE
#define MGLEdgeInsetsZero UIEdgeInsetsZero
#else
#define MGLEdgeInsetsZero NSEdgeInsetsZero
#endif

static MGLMapView *mapView;

Expand Down Expand Up @@ -27,18 +34,122 @@ - (void)testCoordinateBoundsConversion {

MGLCoordinateBounds leftAntimeridianBounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(-75, 175), CLLocationCoordinate2DMake(75, 180));
CGRect leftAntimeridianBoundsRect = [mapView convertCoordinateBounds:leftAntimeridianBounds toRectToView:mapView];

MGLCoordinateBounds rightAntimeridianBounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(-75, -180), CLLocationCoordinate2DMake(75, -175));
CGRect rightAntimeridianBoundsRect = [mapView convertCoordinateBounds:rightAntimeridianBounds toRectToView:mapView];

MGLCoordinateBounds spanningBounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(24, 140), CLLocationCoordinate2DMake(44, 240));
CGRect spanningBoundsRect = [mapView convertCoordinateBounds:spanningBounds toRectToView:mapView];

// If the resulting CGRect from -convertCoordinateBounds:toRectToView:
// intersects the set of bounds to the left and right of the
// antimeridian, then we know that the CGRect spans across the antimeridian
XCTAssertTrue(CGRectIntersectsRect(spanningBoundsRect, leftAntimeridianBoundsRect), @"Resulting");
XCTAssertTrue(CGRectIntersectsRect(spanningBoundsRect, rightAntimeridianBoundsRect), @"Something");
}

#if TARGET_OS_IPHONE
- (void)testUserTrackingModeCompletion {
__block BOOL completed = NO;
[mapView setUserTrackingMode:MGLUserTrackingModeNone animated:NO completionHandler:^{

This comment was marked as resolved.

completed = YES;
}];
XCTAssertTrue(completed, @"Completion block should get called synchronously when the mode is unchanged.");

completed = NO;
[mapView setUserTrackingMode:MGLUserTrackingModeNone animated:YES completionHandler:^{
completed = YES;
}];
XCTAssertTrue(completed, @"Completion block should get called synchronously when the mode is unchanged.");

completed = NO;
[mapView setUserTrackingMode:MGLUserTrackingModeFollow animated:NO completionHandler:^{
completed = YES;
}];
XCTAssertTrue(completed, @"Completion block should get called synchronously when there’s no location.");

completed = NO;
[mapView setUserTrackingMode:MGLUserTrackingModeFollowWithHeading animated:YES completionHandler:^{
completed = YES;
}];
XCTAssertTrue(completed, @"Completion block should get called synchronously when there’s no location.");
}

- (void)testTargetCoordinateCompletion {
__block BOOL completed = NO;
[mapView setTargetCoordinate:kCLLocationCoordinate2DInvalid animated:NO completionHandler:^{
completed = YES;
}];
XCTAssertTrue(completed, @"Completion block should get called synchronously when the target coordinate is unchanged.");

completed = NO;
[mapView setTargetCoordinate:kCLLocationCoordinate2DInvalid animated:YES completionHandler:^{
completed = YES;
}];
XCTAssertTrue(completed, @"Completion block should get called synchronously when the target coordinate is unchanged.");

completed = NO;
[mapView setUserTrackingMode:MGLUserTrackingModeFollow animated:NO completionHandler:nil];
[mapView setTargetCoordinate:CLLocationCoordinate2DMake(39.128106, -84.516293) animated:YES completionHandler:^{
completed = YES;
}];
XCTAssertTrue(completed, @"Completion block should get called synchronously when not tracking user course.");

completed = NO;
[mapView setUserTrackingMode:MGLUserTrackingModeFollowWithCourse animated:NO completionHandler:nil];
[mapView setTargetCoordinate:CLLocationCoordinate2DMake(39.224407, -84.394957) animated:YES completionHandler:^{
completed = YES;
}];
XCTAssertTrue(completed, @"Completion block should get called synchronously when there’s no location.");
}
#endif

- (void)testVisibleCoordinatesCompletion {
XCTestExpectation *expectation = [self expectationWithDescription:@"Completion block should get called when not animated"];
MGLCoordinateBounds unitBounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(0, 0), CLLocationCoordinate2DMake(1, 1));
[mapView setVisibleCoordinateBounds:unitBounds edgePadding:MGLEdgeInsetsZero animated:NO completionHandler:^{
[expectation fulfill];
}];
[self waitForExpectations:@[expectation] timeout:1];

#if TARGET_OS_IPHONE
expectation = [self expectationWithDescription:@"Completion block should get called when animated"];
CLLocationCoordinate2D antiunitCoordinates[] = {
CLLocationCoordinate2DMake(0, 0),
CLLocationCoordinate2DMake(-1, -1),
};
[mapView setVisibleCoordinates:antiunitCoordinates
count:sizeof(antiunitCoordinates) / sizeof(antiunitCoordinates[0])
edgePadding:UIEdgeInsetsZero
direction:0
duration:0
animationTimingFunction:nil
completionHandler:^{
[expectation fulfill];
}];
[self waitForExpectations:@[expectation] timeout:1];
#endif
}

- (void)testShowAnnotationsCompletion {
__block BOOL completed = NO;
[mapView showAnnotations:@[] edgePadding:MGLEdgeInsetsZero animated:NO completionHandler:^{
completed = YES;
}];
XCTAssertTrue(completed, @"Completion block should get called synchronously when there are no annotations to show.");

XCTestExpectation *expectation = [self expectationWithDescription:@"Completion block should get called when not animated"];
MGLPointAnnotation *annotation = [[MGLPointAnnotation alloc] init];
[mapView showAnnotations:@[annotation] edgePadding:MGLEdgeInsetsZero animated:NO completionHandler:^{
[expectation fulfill];
}];
[self waitForExpectations:@[expectation] timeout:1];

expectation = [self expectationWithDescription:@"Completion block should get called when animated."];
[mapView showAnnotations:@[annotation] edgePadding:MGLEdgeInsetsZero animated:YES completionHandler:^{
[expectation fulfill];
}];
[self waitForExpectations:@[expectation] timeout:1];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We’ve had problems with expectations timing out in the past on CI. Since this method doesn’t accept a duration that can be set to 0 (should it?), I’d remove the expectation at the first sign of trouble on CI.

}

@end
7 changes: 7 additions & 0 deletions platform/ios/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
## 5.2.0

* Fixed an issue where the two-finger tilt gesture would continue after lifting one finger. ([#14969](https://github.com/mapbox/mapbox-gl-native/pull/14969))
* Added variants of several animated `MGLMapView` methods that accept completion handlers ([#14381](https://github.com/mapbox/mapbox-gl-native/pull/14381)):
* `-[MGLMapView setVisibleCoordinateBounds:edgePadding:animated:completionHandler:]`
* `-[MGLMapView setContentInset:animated:completionHandler:]`
* `-[MGLMapView setUserTrackingMode:animated:completionHandler:]`
* `-[MGLMapView setTargetCoordinate:animated:completionHandler:]`
* `-[MGLMapView showAnnotations:edgePadding:animated:completionHandler:]`
* `-[MGLMapView selectAnnotation:animated:completionHandler:]`

## 5.1.0 - June 19, 2019

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,16 @@ - (void)internalTestOffscreenSelectionTitle:(NSString*)title withTestData:(PanTe
// Also note, that at this point, the internal mechanism that determines if
// an annotation view is offscreen and should be put back in the reuse queue
// will have run, and `viewForAnnotation` may return nil

[self.mapView selectAnnotation:point moveIntoView:moveIntoView animateSelection:animateSelection];

XCTestExpectation *selectionCompleted = [self expectationWithDescription:@"Selection completed"];
[self.mapView selectAnnotation:point moveIntoView:moveIntoView animateSelection:animateSelection completionHandler:^{
[selectionCompleted fulfill];
}];

// Animated selection takes MGLAnimationDuration (0.3 seconds), so wait a little
// longer. We don't need to wait as long if we're not animated (but we do
// want the runloop to tick over)
[self waitFor:animateSelection ? 0.4: 0.05];
[self waitForExpectations:@[selectionCompleted] timeout:animateSelection ? 0.4: 0.05];

UIView *annotationViewAfterSelection = [self.mapView viewForAnnotation:point];
CLLocationCoordinate2D mapCenterAfterSelection = self.mapView.centerCoordinate;
Expand Down
Loading