summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--platform/darwin/src/MGLMapCamera.h14
-rw-r--r--platform/darwin/src/MGLMapCamera.mm19
-rw-r--r--platform/darwin/test/MGLGeometryTests.mm54
-rw-r--r--platform/ios/CHANGELOG.md8
-rw-r--r--platform/ios/docs/guides/Gesture Recognizers.md38
-rw-r--r--platform/ios/docs/img/user-interaction/RotateSydney.gifbin0 -> 5064046 bytes
-rw-r--r--platform/ios/docs/img/user-interaction/quickzoom.gifbin0 -> 7186288 bytes
-rwxr-xr-xplatform/ios/framework/strip-frameworks.sh19
-rw-r--r--platform/ios/jazzy.yml1
-rw-r--r--platform/ios/src/MGLMapView.mm77
-rw-r--r--platform/ios/uitest/MapViewTests.m17
-rw-r--r--platform/macos/CHANGELOG.md9
-rw-r--r--platform/macos/Mapbox-macOS-SDK-symbols.podspec2
-rw-r--r--platform/macos/Mapbox-macOS-SDK.podspec2
-rw-r--r--platform/macos/app/AppDelegate.m11
-rw-r--r--platform/macos/app/Base.lproj/MainMenu.xib6
-rw-r--r--platform/macos/app/MapDocument.m15
-rw-r--r--platform/macos/src/MGLMapView.mm50
18 files changed, 251 insertions, 91 deletions
diff --git a/platform/darwin/src/MGLMapCamera.h b/platform/darwin/src/MGLMapCamera.h
index a76405df6f..7ce5927d1d 100644
--- a/platform/darwin/src/MGLMapCamera.h
+++ b/platform/darwin/src/MGLMapCamera.h
@@ -67,6 +67,20 @@ MGL_EXPORT
pitch:(CGFloat)pitch
heading:(CLLocationDirection)heading;
+/**
+ Returns a Boolean value indicating whether the given camera is functionally
+ equivalent to the receiver.
+
+ Unlike `-isEqual:`, this method returns `YES` if the difference between the
+ coordinates, altitudes, pitches, or headings of the two camera objects is
+ negligible.
+
+ @param otherCamera The camera with which to compare the receiver.
+ @return A Boolean value indicating whether the two cameras are functionally
+ equivalent.
+ */
+- (BOOL)isEqualToMapCamera:(MGLMapCamera *)otherCamera;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLMapCamera.mm b/platform/darwin/src/MGLMapCamera.mm
index 260ea31bbd..613124da66 100644
--- a/platform/darwin/src/MGLMapCamera.mm
+++ b/platform/darwin/src/MGLMapCamera.mm
@@ -2,6 +2,11 @@
#include <mbgl/util/projection.hpp>
+BOOL MGLEqualFloatWithAccuracy(CGFloat left, CGFloat right, CGFloat accuracy)
+{
+ return MAX(left, right) - MIN(left, right) <= accuracy;
+}
+
@implementation MGLMapCamera
+ (BOOL)supportsSecureCoding
@@ -116,6 +121,20 @@
&& _pitch == otherCamera.pitch && _heading == otherCamera.heading);
}
+- (BOOL)isEqualToMapCamera:(MGLMapCamera *)otherCamera
+{
+ if (otherCamera == self)
+ {
+ return YES;
+ }
+
+ return (MGLEqualFloatWithAccuracy(_centerCoordinate.latitude, otherCamera.centerCoordinate.latitude, 1e-6)
+ && MGLEqualFloatWithAccuracy(_centerCoordinate.longitude, otherCamera.centerCoordinate.longitude, 1e-6)
+ && MGLEqualFloatWithAccuracy(_altitude, otherCamera.altitude, 1e-6)
+ && MGLEqualFloatWithAccuracy(_pitch, otherCamera.pitch, 1)
+ && MGLEqualFloatWithAccuracy(_heading, otherCamera.heading, 1));
+}
+
- (NSUInteger)hash
{
return (@(_centerCoordinate.latitude).hash + @(_centerCoordinate.longitude).hash
diff --git a/platform/darwin/test/MGLGeometryTests.mm b/platform/darwin/test/MGLGeometryTests.mm
index 448145157d..220a837643 100644
--- a/platform/darwin/test/MGLGeometryTests.mm
+++ b/platform/darwin/test/MGLGeometryTests.mm
@@ -15,42 +15,42 @@
}
- (void)testAngleConversions {
- XCTAssertEqualWithAccuracy(-180, MGLDegreesFromRadians(-M_PI), 5);
+ XCTAssertEqualWithAccuracy(-180, MGLDegreesFromRadians(-M_PI), 1e-5);
XCTAssertEqual(0, MGLDegreesFromRadians(0));
- XCTAssertEqualWithAccuracy(45, MGLDegreesFromRadians(M_PI_4), 5);
- XCTAssertEqualWithAccuracy(90, MGLDegreesFromRadians(M_PI_2), 5);
- XCTAssertEqualWithAccuracy(180, MGLDegreesFromRadians(M_PI), 5);
- XCTAssertEqualWithAccuracy(360, MGLDegreesFromRadians(2 * M_PI), 5);
- XCTAssertEqualWithAccuracy(720, MGLDegreesFromRadians(4 * M_PI), 5);
-
- XCTAssertEqualWithAccuracy(-360, MGLDegreesFromRadians(MGLRadiansFromDegrees(-360)), 4);
- XCTAssertEqualWithAccuracy(-180, MGLDegreesFromRadians(MGLRadiansFromDegrees(-180)), 5);
- XCTAssertEqualWithAccuracy(-90, MGLDegreesFromRadians(MGLRadiansFromDegrees(-90)), 5);
- XCTAssertEqualWithAccuracy(-45, MGLDegreesFromRadians(MGLRadiansFromDegrees(-45)), 5);
- XCTAssertEqualWithAccuracy(0, MGLDegreesFromRadians(MGLRadiansFromDegrees(0)), 5);
- XCTAssertEqualWithAccuracy(45, MGLDegreesFromRadians(MGLRadiansFromDegrees(45)), 5);
- XCTAssertEqualWithAccuracy(90, MGLDegreesFromRadians(MGLRadiansFromDegrees(90)), 5);
- XCTAssertEqualWithAccuracy(180, MGLDegreesFromRadians(MGLRadiansFromDegrees(180)), 5);
- XCTAssertEqualWithAccuracy(360, MGLDegreesFromRadians(MGLRadiansFromDegrees(360)), 4);
+ XCTAssertEqualWithAccuracy(45, MGLDegreesFromRadians(M_PI_4), 1e-5);
+ XCTAssertEqualWithAccuracy(90, MGLDegreesFromRadians(M_PI_2), 1e-5);
+ XCTAssertEqualWithAccuracy(180, MGLDegreesFromRadians(M_PI), 1e-5);
+ XCTAssertEqualWithAccuracy(360, MGLDegreesFromRadians(2 * M_PI), 1e-5);
+ XCTAssertEqualWithAccuracy(720, MGLDegreesFromRadians(4 * M_PI), 1e-5);
+
+ XCTAssertEqualWithAccuracy(-360, MGLDegreesFromRadians(MGLRadiansFromDegrees(-360)), 1e-4);
+ XCTAssertEqualWithAccuracy(-180, MGLDegreesFromRadians(MGLRadiansFromDegrees(-180)), 1e-5);
+ XCTAssertEqualWithAccuracy(-90, MGLDegreesFromRadians(MGLRadiansFromDegrees(-90)), 1e-5);
+ XCTAssertEqualWithAccuracy(-45, MGLDegreesFromRadians(MGLRadiansFromDegrees(-45)), 1e-5);
+ XCTAssertEqualWithAccuracy(0, MGLDegreesFromRadians(MGLRadiansFromDegrees(0)), 1e-5);
+ XCTAssertEqualWithAccuracy(45, MGLDegreesFromRadians(MGLRadiansFromDegrees(45)), 1e-5);
+ XCTAssertEqualWithAccuracy(90, MGLDegreesFromRadians(MGLRadiansFromDegrees(90)), 1e-5);
+ XCTAssertEqualWithAccuracy(180, MGLDegreesFromRadians(MGLRadiansFromDegrees(180)), 1e-5);
+ XCTAssertEqualWithAccuracy(360, MGLDegreesFromRadians(MGLRadiansFromDegrees(360)), 1e-4);
}
- (void)testAltitudeConversions {
CGSize tallSize = CGSizeMake(600, 1200);
CGSize midSize = CGSizeMake(600, 800);
CGSize shortSize = CGSizeMake(600, 400);
-
- XCTAssertEqualWithAccuracy(1800, MGLAltitudeForZoomLevel(MGLZoomLevelForAltitude(1800, 0, 0, midSize), 0, 0, midSize), 1);
+
+ XCTAssertEqualWithAccuracy(1800, MGLAltitudeForZoomLevel(MGLZoomLevelForAltitude(1800, 0, 0, midSize), 0, 0, midSize), 1e-8);
XCTAssertLessThan(MGLZoomLevelForAltitude(1800, 0, 0, midSize), MGLZoomLevelForAltitude(1800, 0, 0, tallSize));
XCTAssertGreaterThan(MGLZoomLevelForAltitude(1800, 0, 0, midSize), MGLZoomLevelForAltitude(1800, 0, 0, shortSize));
-
- XCTAssertEqualWithAccuracy(0, MGLZoomLevelForAltitude(MGLAltitudeForZoomLevel(0, 0, 0, midSize), 0, 0, midSize), 3);
- XCTAssertEqualWithAccuracy(18, MGLZoomLevelForAltitude(MGLAltitudeForZoomLevel(18, 0, 0, midSize), 0, 0, midSize), 3);
-
- XCTAssertEqualWithAccuracy(0, MGLZoomLevelForAltitude(MGLAltitudeForZoomLevel(0, 0, 40, midSize), 0, 40, midSize), 3);
- XCTAssertEqualWithAccuracy(18, MGLZoomLevelForAltitude(MGLAltitudeForZoomLevel(18, 0, 40, midSize), 0, 40, midSize), 3);
-
- XCTAssertEqualWithAccuracy(0, MGLZoomLevelForAltitude(MGLAltitudeForZoomLevel(0, 60, 40, midSize), 60, 40, midSize), 3);
- XCTAssertEqualWithAccuracy(18, MGLZoomLevelForAltitude(MGLAltitudeForZoomLevel(18, 60, 40, midSize), 60, 40, midSize), 3);
+
+ XCTAssertEqualWithAccuracy(0, MGLZoomLevelForAltitude(MGLAltitudeForZoomLevel(0, 0, 0, midSize), 0, 0, midSize), 1e-8);
+ XCTAssertEqualWithAccuracy(18, MGLZoomLevelForAltitude(MGLAltitudeForZoomLevel(18, 0, 0, midSize), 0, 0, midSize), 1e-8);
+
+ XCTAssertEqualWithAccuracy(0, MGLZoomLevelForAltitude(MGLAltitudeForZoomLevel(0, 0, 40, midSize), 0, 40, midSize), 1e-8);
+ XCTAssertEqualWithAccuracy(18, MGLZoomLevelForAltitude(MGLAltitudeForZoomLevel(18, 0, 40, midSize), 0, 40, midSize), 1e-8);
+
+ XCTAssertEqualWithAccuracy(0, MGLZoomLevelForAltitude(MGLAltitudeForZoomLevel(0, 60, 40, midSize), 60, 40, midSize), 1e-8);
+ XCTAssertEqualWithAccuracy(18, MGLZoomLevelForAltitude(MGLAltitudeForZoomLevel(18, 60, 40, midSize), 60, 40, midSize), 1e-8);
}
- (void)testGeometryBoxing {
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index 7450325c93..a4f7d73849 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -51,6 +51,14 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* Added a `MGLDistanceFormatter` class for formatting geographic distances. ([#7888](https://github.com/mapbox/mapbox-gl-native/pull/7888))
* Fixed an issue that was causing the system location indicator to stay on in background after telemetry was disabled. ([#7833](https://github.com/mapbox/mapbox-gl-native/pull/7833))
+## 3.4.2 - February 21, 2017
+
+This is the final scheduled version of the Mapbox iOS SDK that supports iOS 7. ([#8129](https://github.com/mapbox/mapbox-gl-native/pull/8129))
+
+* A programmatic change to an MGLMapView’s camera no longer resets the user tracking mode. ([#7856](https://github.com/mapbox/mapbox-gl-native/pull/7856))
+* Improved the performance of trivial camera animations. ([#7125](https://github.com/mapbox/mapbox-gl-native/pull/7125))
+* Added a guide detailing the built-in gesture recognizers and various ways to configure them. ([#7937](https://github.com/mapbox/mapbox-gl-native/pull/7937))
+
## 3.4.1 - January 25, 2017
* Fixed a build error in the static framework flavor of this SDK caused by a missing header. ([#7844](https://github.com/mapbox/mapbox-gl-native/pull/7844))
diff --git a/platform/ios/docs/guides/Gesture Recognizers.md b/platform/ios/docs/guides/Gesture Recognizers.md
new file mode 100644
index 0000000000..08e4c150e1
--- /dev/null
+++ b/platform/ios/docs/guides/Gesture Recognizers.md
@@ -0,0 +1,38 @@
+# User Interactions
+
+The Mapbox iOS SDK provides a set of built-in gesture recognizers. You can customize or supplement these gestures according to your use case. You see what gesture recognizers are on your `MGLMapView` by accessing the `gestureRecognizers` property on your map.
+
+## Configuring user interaction
+
+Several properties on an `MGLMapView` provide ways to enable or disable a set of gesture recognizers. Boolean values are set to `YES` by default.
+
+- `zoomEnabled` - Allows the user to zoom in or out by pinching two fingers, double-tapping, tapping with two fingers, or double-tapping then dragging vertically. Accepts Boolean values.
+- `scrollEnabled` - Allows the user to scroll by dragging or swiping one finger. Accepts Boolean values.
+- `rotateEnabled` - Allows the user to rotate by moving two fingers in a circular motion. Accepts Boolean values.
+- `pitchEnabled` - Allows the user to tilt the map by vertically dragging two fingers. Accepts Boolean values.
+- `decelerationRate` - Determines the rate of deceleration after the user lifts their finger. You can set the value using the `MGLMapViewDecelerationRateNormal`, `MGLMapViewDecelerationRateFast`, or `MGLMapViewDecelerationRateImmediate` constants.
+
+## Individual gestures
+
+|Gesture | Description | Related Property |
+|:-------:|----------------| -----------|
+|Pinch | Zooms in or out on the map's anchor point | `zoomEnabled` |
+|Rotation | Changes the MGLMapView direction based on the user rotating two fingers in a circular motion | `rotateEnabled` |
+|Single tap | Selects/deselects the annotation that you tap. | |
+|Double tap | Zooms in on the map's anchor point | `zoomEnabled` |
+|Two-finger tap | Zooms out with the map's anchor point centered | `zoomEnabled` |
+|Pan | Scrolls across mapView (_note: if_ `MGLUserTrackingModeFollow` _is being used, it will be disabled once the user pans_)| `scrollEnabled` |
+|Two-finger drag | Adjusts the pitch of the `MGLMapView` | `pitchEnabled` |
+|One-finger zoom | Tap twice; on second tap, hold your finger on the map and pan up to zoom in, or down to zoom out | `zoomEnabled`|
+
+![quick zoom](img/user-interaction/quickzoom.gif) ![rotation](img/user-interaction/RotateSydney.gif)
+
+## Adding custom gesture recognizers
+
+You can add `UIGestureRecognizers` to your map programmatically or via storyboard. Adding custom responses to gesture recognizers can enhance your user's experience, but try to use standard gestures where possible.
+
+The gesture recognizers that you add will take priority over the built-in gesture recognizer. You can also set up your own gesture recognizer to work simultaneously with built-in gesture recognizers by using `-gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:`, allowing you to enhance already existing gesture recognizers.
+
+You can also add gesture recognizers that are only called when the default gesture recognizer fails (and vice versa), such as when a user taps on a part of the map that is not an annotation. The documentation for [MGLMapView](Classes/MGLMapView.html) includes an example of how to create a fallback gesture recognizer.
+
+If you would like to disable a specific set of gesture recognizers, such as zoom, you can set the Boolean value for the appropriate property to `NO`. You can then add your own gesture recognizers to perform those actions.
diff --git a/platform/ios/docs/img/user-interaction/RotateSydney.gif b/platform/ios/docs/img/user-interaction/RotateSydney.gif
new file mode 100644
index 0000000000..5ee840e04b
--- /dev/null
+++ b/platform/ios/docs/img/user-interaction/RotateSydney.gif
Binary files differ
diff --git a/platform/ios/docs/img/user-interaction/quickzoom.gif b/platform/ios/docs/img/user-interaction/quickzoom.gif
new file mode 100644
index 0000000000..79aa9e8dce
--- /dev/null
+++ b/platform/ios/docs/img/user-interaction/quickzoom.gif
Binary files differ
diff --git a/platform/ios/framework/strip-frameworks.sh b/platform/ios/framework/strip-frameworks.sh
index 9deb404ca1..686541566a 100755
--- a/platform/ios/framework/strip-frameworks.sh
+++ b/platform/ios/framework/strip-frameworks.sh
@@ -35,9 +35,19 @@ code_sign() {
/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements "$1"
}
-echo "Stripping frameworks"
+# Set working directory to product’s embedded frameworks
cd "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+if [ "$ACTION" = "install" ]; then
+ echo "Copy .bcsymbolmap files to .xcarchive"
+ find . -name '*.bcsymbolmap' -type f -exec mv {} "${CONFIGURATION_BUILD_DIR}" \;
+else
+ # Delete *.bcsymbolmap files from framework bundle unless archiving
+ find . -name '*.bcsymbolmap' -type f -exec rm -rf "{}" +\;
+fi
+
+echo "Stripping frameworks"
+
for file in $(find . -type f -perm +111); do
# Skip non-dynamic libraries
if ! [[ "$(file "$file")" == *"dynamically linked shared library"* ]]; then
@@ -61,10 +71,3 @@ for file in $(find . -type f -perm +111); do
fi
done
-if [ "$ACTION" = "install" ]; then
- echo "Copy .bcsymbolmap files to .xcarchive"
- find . -name '*.bcsymbolmap' -type f -exec mv {} "${CONFIGURATION_BUILD_DIR}" \;
-else
- # Delete *.bcsymbolmap files from framework bundle unless archiving
- find . -name '*.bcsymbolmap' -type f -exec rm -rf "{}" +\;
-fi
diff --git a/platform/ios/jazzy.yml b/platform/ios/jazzy.yml
index cea77adfab..9a119db31e 100644
--- a/platform/ios/jazzy.yml
+++ b/platform/ios/jazzy.yml
@@ -23,6 +23,7 @@ custom_categories:
- Working with GeoJSON Data
- For Style Authors
- Info.plist Keys
+ - Gesture Recognizers
- name: Maps
children:
- MGLAccountManager
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index bb329ccda7..7119544158 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -2414,8 +2414,6 @@ public:
- (void)_setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate edgePadding:(UIEdgeInsets)insets zoomLevel:(double)zoomLevel direction:(CLLocationDirection)direction duration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function completionHandler:(nullable void (^)(void))completion
{
- _mbglMap->cancelTransitions();
-
mbgl::CameraOptions cameraOptions;
cameraOptions.center = MGLLatLngFromLocationCoordinate2D(centerCoordinate);
cameraOptions.padding = MGLEdgeInsetsFromNSEdgeInsets(insets);
@@ -2442,6 +2440,20 @@ public:
});
};
}
+
+ MGLMapCamera *camera = [self cameraForCameraOptions:cameraOptions];
+ if ([self.camera isEqualToMapCamera:camera])
+ {
+ if (completion)
+ {
+ [self animateWithDelay:duration animations:^{
+ completion();
+ }];
+ }
+ return;
+ }
+
+ _mbglMap->cancelTransitions();
_mbglMap->easeTo(cameraOptions, animationOptions);
}
@@ -2560,9 +2572,6 @@ public:
- (void)_setVisibleCoordinates:(const CLLocationCoordinate2D *)coordinates count:(NSUInteger)count edgePadding:(UIEdgeInsets)insets direction:(CLLocationDirection)direction duration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function completionHandler:(nullable void (^)(void))completion
{
- _mbglMap->cancelTransitions();
-
- [self willChangeValueForKey:@"visibleCoordinateBounds"];
mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(insets);
padding += MGLEdgeInsetsFromNSEdgeInsets(self.contentInset);
std::vector<mbgl::LatLng> latLngs;
@@ -2592,6 +2601,21 @@ public:
});
};
}
+
+ MGLMapCamera *camera = [self cameraForCameraOptions:cameraOptions];
+ if ([self.camera isEqualToMapCamera:camera])
+ {
+ if (completion)
+ {
+ [self animateWithDelay:duration animations:^{
+ completion();
+ }];
+ }
+ return;
+ }
+
+ [self willChangeValueForKey:@"visibleCoordinateBounds"];
+ _mbglMap->cancelTransitions();
_mbglMap->easeTo(cameraOptions, animationOptions);
[self didChangeValueForKey:@"visibleCoordinateBounds"];
}
@@ -2677,14 +2701,6 @@ public:
- (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function completionHandler:(nullable void (^)(void))completion
{
- self.userTrackingMode = MGLUserTrackingModeNone;
- _mbglMap->cancelTransitions();
- if ([self.camera isEqual:camera])
- {
- return;
- }
-
- mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:self.contentInset];
mbgl::AnimationOptions animationOptions;
if (duration > 0)
{
@@ -2699,8 +2715,21 @@ public:
});
};
}
+
+ if ([self.camera isEqualToMapCamera:camera])
+ {
+ if (completion)
+ {
+ [self animateWithDelay:duration animations:^{
+ completion();
+ }];
+ }
+ return;
+ }
[self willChangeValueForKey:@"camera"];
+ _mbglMap->cancelTransitions();
+ mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:self.contentInset];
_mbglMap->easeTo(cameraOptions, animationOptions);
[self didChangeValueForKey:@"camera"];
}
@@ -2717,20 +2746,11 @@ public:
- (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration peakAltitude:(CLLocationDistance)peakAltitude completionHandler:(nullable void (^)(void))completion
{
- self.userTrackingMode = MGLUserTrackingModeNone;
-
[self _flyToCamera:camera edgePadding:self.contentInset withDuration:duration peakAltitude:peakAltitude completionHandler:completion];
}
- (void)_flyToCamera:(MGLMapCamera *)camera edgePadding:(UIEdgeInsets)insets withDuration:(NSTimeInterval)duration peakAltitude:(CLLocationDistance)peakAltitude completionHandler:(nullable void (^)(void))completion
{
- _mbglMap->cancelTransitions();
- if ([self.camera isEqual:camera])
- {
- return;
- }
-
- mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:insets];
mbgl::AnimationOptions animationOptions;
if (duration >= 0)
{
@@ -2751,8 +2771,21 @@ public:
});
};
}
+
+ if ([self.camera isEqualToMapCamera:camera])
+ {
+ if (completion)
+ {
+ [self animateWithDelay:duration animations:^{
+ completion();
+ }];
+ }
+ return;
+ }
[self willChangeValueForKey:@"camera"];
+ _mbglMap->cancelTransitions();
+ mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:insets];
_mbglMap->flyTo(cameraOptions, animationOptions);
[self didChangeValueForKey:@"camera"];
}
diff --git a/platform/ios/uitest/MapViewTests.m b/platform/ios/uitest/MapViewTests.m
index 3ed8c840f4..4ed3d89399 100644
--- a/platform/ios/uitest/MapViewTests.m
+++ b/platform/ios/uitest/MapViewTests.m
@@ -320,6 +320,23 @@
@"setting zoom should take effect");
}
+- (void)testCameraDebouncing {
+ MGLMapCamera *camera = [MGLMapCamera cameraLookingAtCenterCoordinate:CLLocationCoordinate2DMake(45, -122)
+ fromDistance:100
+ pitch:30
+ heading:45];
+ tester.mapView.camera = camera;
+ XCTAssertEqualObjects(tester.mapView.camera, camera);
+
+ [tester.mapView setCamera:camera withDuration:10 animationTimingFunction:nil completionHandler:^{
+ XCTAssert(NO, @"Camera animation should not be canceled by redundantly setting the camera to the current camera.");
+ }];
+ XCTAssertEqualObjects(tester.mapView.camera, camera);
+
+ tester.mapView.camera = camera;
+ XCTAssertEqualObjects(tester.mapView.camera, camera);
+}
+
- (void)testMarkerSelection {
CGPoint point = CGPointMake(100, 100);
MGLPointAnnotation *marker = [MGLPointAnnotation new];
diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md
index a9a9473af2..8b05211c5a 100644
--- a/platform/macos/CHANGELOG.md
+++ b/platform/macos/CHANGELOG.md
@@ -8,7 +8,6 @@
* Improved the line wrapping behavior of point-placed labels, especially labels written in Chinese and Japanese. ([#6828](https://github.com/mapbox/mapbox-gl-native/pull/6828), [#7446](https://github.com/mapbox/mapbox-gl-native/pull/7446))
* CJK characters now remain upright in vertically oriented labels that have line placement, such as road labels. ([#7114](https://github.com/mapbox/mapbox-gl-native/issues/7114))
* Added Chinese (Simplified and Traditional), French, German, Japanese, Lithuanian, Polish, Portuguese (Brazilian), Spanish, Swedish, Ukrainian, and Vietnamese localizations. ([#7316](https://github.com/mapbox/mapbox-gl-native/pull/7316), [#7503](https://github.com/mapbox/mapbox-gl-native/pull/7503), [#7899](https://github.com/mapbox/mapbox-gl-native/pull/7899), [#7999](https://github.com/mapbox/mapbox-gl-native/pull/7999))
-* Fixed an issue that let the app crash when moving the window between screens. ([#8004](https://github.com/mapbox/mapbox-gl-native/pull/8004))
### Styles
@@ -48,14 +47,16 @@
* Fixed flickering that occurred when panning past the antimeridian. ([#7574](https://github.com/mapbox/mapbox-gl-native/pull/7574))
* Added a `MGLDistanceFormatter` class for formatting geographic distances. ([#7888](https://github.com/mapbox/mapbox-gl-native/pull/7888))
-## 0.3.1
+## 0.3.1 - February 21, 2017
-This version of the Mapbox macOS SDK corresponds to version 3.4.1 of the Mapbox iOS SDK. The two SDKs have very similar feature sets. The main differences are the lack of user location tracking and annotation views. Some APIs have been adapted to macOS conventions, particularly the use of NSPopover for callout views.
+This version of the Mapbox macOS SDK corresponds to version 3.4.2 of the Mapbox iOS SDK.
* Fixed an issue causing MGLMapView’s `camera`’s `heading` to be set to a negative value, indicating an undefined heading, when the map view faces northwest. The heading is now wrapped to between zero and 360 degrees, for consistency with MGLMapView’s `direction` property. ([#7724](https://github.com/mapbox/mapbox-gl-native/pull/7724))
-* Allows use of the integrated GPU on machines that have more than one GPU. Follow [Apple’s Technical QA1734](https://developer.apple.com/library/content/qa/qa1734/_index.html) to enable this in your app. ([#7834](https://github.com/mapbox/mapbox-gl-native/pull/7834))
+* Fixed a crash that occurred when moving a window containing an MGLMapView from one screen to another. ([#8004](https://github.com/mapbox/mapbox-gl-native/pull/8004))
+* Fixed an issue preventing the use of the integrated GPU on machines that have more than one GPU. Follow the instructions in [Technical Q&A 1734](https://developer.apple.com/library/content/qa/qa1734/_index.html) to enable integrated GPU usage in your application. ([#7834](https://github.com/mapbox/mapbox-gl-native/pull/7834))
* Fixed an issue causing the mouse cursor to jump after shift- or option-dragging a map view if the window opened on a screen with a different size than the screen with keyboard focus. ([#7846](https://github.com/mapbox/mapbox-gl-native/pull/7846))
* Deprecated the style class methods in MGLStyle. ([#7785](https://github.com/mapbox/mapbox-gl-native/pull/7785))
+* Improved the performance of trivial camera animations. ([#7125](https://github.com/mapbox/mapbox-gl-native/pull/7125))
## 0.3.0 - January 21, 2016
diff --git a/platform/macos/Mapbox-macOS-SDK-symbols.podspec b/platform/macos/Mapbox-macOS-SDK-symbols.podspec
index 0a0875ccb8..c17e665512 100644
--- a/platform/macos/Mapbox-macOS-SDK-symbols.podspec
+++ b/platform/macos/Mapbox-macOS-SDK-symbols.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |m|
- version = '0.3.0'
+ version = '0.3.1'
m.name = 'Mapbox-macOS-SDK-symbols'
m.version = "#{version}-symbols"
diff --git a/platform/macos/Mapbox-macOS-SDK.podspec b/platform/macos/Mapbox-macOS-SDK.podspec
index 029ab4b3e2..a6f2d2838b 100644
--- a/platform/macos/Mapbox-macOS-SDK.podspec
+++ b/platform/macos/Mapbox-macOS-SDK.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |m|
- version = '0.3.0'
+ version = '0.3.1'
m.name = 'Mapbox-macOS-SDK'
m.version = version
diff --git a/platform/macos/app/AppDelegate.m b/platform/macos/app/AppDelegate.m
index 5b848cc79b..0d780424f9 100644
--- a/platform/macos/app/AppDelegate.m
+++ b/platform/macos/app/AppDelegate.m
@@ -71,7 +71,7 @@ NSString * const MGLLastMapDebugMaskDefaultsKey = @"MGLLastMapDebugMask";
@end
-@interface AppDelegate ()
+@interface AppDelegate () <NSWindowDelegate>
@property (weak) IBOutlet NSArrayController *offlinePacksArrayController;
@property (weak) IBOutlet NSPanel *offlinePacksPanel;
@@ -294,4 +294,13 @@ NSString * const MGLLastMapDebugMaskDefaultsKey = @"MGLLastMapDebugMask";
return NO;
}
+#pragma mark NSWindowDelegate methods
+
+- (void)windowWillClose:(NSNotification *)notification {
+ NSWindow *window = notification.object;
+ if (window == self.preferencesWindow) {
+ [window makeFirstResponder:nil];
+ }
+}
+
@end
diff --git a/platform/macos/app/Base.lproj/MainMenu.xib b/platform/macos/app/Base.lproj/MainMenu.xib
index b6d2a50309..941bed2136 100644
--- a/platform/macos/app/Base.lproj/MainMenu.xib
+++ b/platform/macos/app/Base.lproj/MainMenu.xib
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11191" systemVersion="15G31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="15G1217" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
- <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11191"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
@@ -703,6 +704,7 @@ CA
</constraints>
</view>
<connections>
+ <outlet property="delegate" destination="Voe-Tx-rLC" id="PNO-Pp-jOX"/>
<outlet property="initialFirstResponder" destination="7sb-sf-oJU" id="UZe-di-dnA"/>
</connections>
<point key="canvasLocation" x="754" y="221"/>
diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m
index 2de189c856..39055d7447 100644
--- a/platform/macos/app/MapDocument.m
+++ b/platform/macos/app/MapDocument.m
@@ -22,10 +22,13 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
NSMutableArray *flattenedShapes = [NSMutableArray arrayWithCapacity:shapes.count];
for (id <MGLAnnotation> shape in shapes) {
NSArray *subshapes;
- // Flatten multipoints but not polylines or polygons.
- if ([shape isMemberOfClass:[MGLMultiPoint class]]) {
- NSUInteger pointCount = [(MGLMultiPoint *)shape pointCount];
- CLLocationCoordinate2D *coordinates = [(MGLMultiPoint *)shape coordinates];
+ if ([shape isKindOfClass:[MGLMultiPolyline class]]) {
+ subshapes = [(MGLMultiPolyline *)shape polylines];
+ } else if ([shape isKindOfClass:[MGLMultiPolygon class]]) {
+ subshapes = [(MGLMultiPolygon *)shape polygons];
+ } else if ([shape isKindOfClass:[MGLPointCollection class]]) {
+ NSUInteger pointCount = [(MGLPointCollection *)shape pointCount];
+ CLLocationCoordinate2D *coordinates = [(MGLPointCollection *)shape coordinates];
NSMutableArray *pointAnnotations = [NSMutableArray arrayWithCapacity:pointCount];
for (NSUInteger i = 0; i < pointCount; i++) {
MGLPointAnnotation *pointAnnotation = [[MGLPointAnnotation alloc] init];
@@ -33,10 +36,6 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
[pointAnnotations addObject:pointAnnotation];
}
subshapes = pointAnnotations;
- } else if ([shape isKindOfClass:[MGLMultiPolyline class]]) {
- subshapes = [(MGLMultiPolyline *)shape polylines];
- } else if ([shape isKindOfClass:[MGLMultiPolygon class]]) {
- subshapes = [(MGLMultiPolygon *)shape polygons];
} else if ([shape isKindOfClass:[MGLShapeCollection class]]) {
subshapes = MBXFlattenedShapes([(MGLShapeCollection *)shape shapes]);
}
diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm
index 7709632d13..827da35076 100644
--- a/platform/macos/src/MGLMapView.mm
+++ b/platform/macos/src/MGLMapView.mm
@@ -616,13 +616,14 @@ public:
// Default to Streets.
if (!styleURL) {
- // An access token is required to load any default style, including
- // Streets.
- if (![MGLAccountManager accessToken]) {
- return;
- }
styleURL = [MGLStyle streetsStyleURLWithVersion:MGLStyleDefaultVersion];
}
+
+ // An access token is required to load any default style, including Streets.
+ if (![MGLAccountManager accessToken] && [styleURL.scheme isEqualToString:@"mapbox"]) {
+ NSLog(@"Cannot set the style URL to %@ because no access token has been specified.", styleURL);
+ return;
+ }
styleURL = styleURL.mgl_URLByStandardizingScheme;
self.style = nil;
@@ -1143,12 +1144,6 @@ public:
}
- (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function completionHandler:(nullable void (^)(void))completion {
- _mbglMap->cancelTransitions();
- if ([self.camera isEqual:camera]) {
- return;
- }
-
- mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera];
mbgl::AnimationOptions animationOptions;
if (duration > 0) {
animationOptions.duration.emplace(MGLDurationInSecondsFromTimeInterval(duration));
@@ -1164,8 +1159,19 @@ public:
});
};
}
+
+ if ([self.camera isEqualToMapCamera:camera]) {
+ if (completion) {
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+ completion();
+ });
+ }
+ return;
+ }
[self willChangeValueForKey:@"camera"];
+ _mbglMap->cancelTransitions();
+ mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera];
_mbglMap->easeTo(cameraOptions, animationOptions);
[self didChangeValueForKey:@"camera"];
}
@@ -1179,12 +1185,6 @@ public:
}
- (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration peakAltitude:(CLLocationDistance)peakAltitude completionHandler:(nullable void (^)(void))completion {
- _mbglMap->cancelTransitions();
- if ([self.camera isEqual:camera]) {
- return;
- }
-
- mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera];
mbgl::AnimationOptions animationOptions;
if (duration >= 0) {
animationOptions.duration = MGLDurationInSecondsFromTimeInterval(duration);
@@ -1205,8 +1205,19 @@ public:
});
};
}
+
+ if ([self.camera isEqualToMapCamera:camera]) {
+ if (completion) {
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+ completion();
+ });
+ }
+ return;
+ }
[self willChangeValueForKey:@"camera"];
+ _mbglMap->cancelTransitions();
+ mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera];
_mbglMap->flyTo(cameraOptions, animationOptions);
[self didChangeValueForKey:@"camera"];
}
@@ -1255,6 +1266,11 @@ public:
if (animated) {
animationOptions.duration = MGLDurationInSecondsFromTimeInterval(MGLAnimationDuration);
}
+
+ MGLMapCamera *camera = [self cameraForCameraOptions:cameraOptions];
+ if ([self.camera isEqualToMapCamera:camera]) {
+ return;
+ }
[self willChangeValueForKey:@"visibleCoordinateBounds"];
animationOptions.transitionFinishFn = ^() {