[core, ios, osx] Only constrain after adding to a window

Introduced a setter/getter for constrain mode. On iOS and OS X, the zoom level inspectable causes the zoom level to be set independently from the longitude and latitude. Thus, the latitude inspectable had no effect because the latitude was constrained to 0 at z0. Temporarily removing the heightwise constraint allows the map to center on the intended location before zooming, which is the usual case for storyboards and XIBs. On iOS, the only guarantee we have timing-wise is that all the inspectables are applied after initialization but before the view is added to a window. So we reimpose the heightwise constraint as soon as the view is added to a window, that is, before the user has a chance to pan the map out of bounds.

Fixes #3868.
This commit is contained in:
Minh Nguyễn
2016-02-10 15:15:29 -08:00
committed by Minh Nguyễn
parent 71611ec612
commit bd59ab9a52
10 changed files with 65 additions and 13 deletions

View File

@@ -54,6 +54,7 @@ Known issues:
- Corrected the dynamic framework’s minimum deployment target to iOS 8.0. ([#3872](https://github.com/mapbox/mapbox-gl-native/pull/3872))
- Fixed Fabric compatibility. ([#3847](https://github.com/mapbox/mapbox-gl-native/pull/3847))
- Fixed a crash that can occur when reselecting an annotation. ([#3881](https://github.com/mapbox/mapbox-gl-native/pull/3881))
- Fixed an issue preventing the Latitude inspectable from working when it is set before setting the Zoom Level inspectable in Interface Builder. ([#3886](https://github.com/mapbox/mapbox-gl-native/pull/3886))
- Fixed an issue preventing `-[MGLMapViewDelegate mapView:tapOnCalloutForAnnotation:]` from being called when a non-custom callout view is tapped. ([#3875](https://github.com/mapbox/mapbox-gl-native/pull/3875))
## iOS 3.1.0

View File

@@ -138,6 +138,10 @@ public:
// North Orientation
void setNorthOrientation(NorthOrientation);
NorthOrientation getNorthOrientation() const;
// Constrain mode
void setConstrainMode(ConstrainMode);
ConstrainMode getConstrainMode() const;
// Size
uint16_t getWidth() const;

View File

@@ -24,6 +24,7 @@ enum class GLContextMode : EnumType {
// We can choose to constrain the map both horizontally or vertically, or only
// vertically e.g. while panning.
enum class ConstrainMode : EnumType {
None,
HeightOnly,
WidthAndHeight,
};

View File

@@ -314,7 +314,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
_mbglFileSource = new mbgl::DefaultFileSource([fileCachePath UTF8String], [[[[NSBundle mainBundle] resourceURL] path] UTF8String]);
// setup mbgl map
_mbglMap = new mbgl::Map(*_mbglView, *_mbglFileSource, mbgl::MapMode::Continuous);
_mbglMap = new mbgl::Map(*_mbglView, *_mbglFileSource, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None);
// start paused if in IB
if (_isTargetingInterfaceBuilder || background) {
@@ -920,6 +920,11 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
BOOL isVisible = self.superview && self.window;
if (isVisible && ! _displayLink)
{
if (_mbglMap->getConstrainMode() == mbgl::ConstrainMode::None)
{
_mbglMap->setConstrainMode(mbgl::ConstrainMode::HeightOnly);
}
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateFromDisplayLink)];
_displayLink.frameInterval = MGLTargetFrameInterval;
[_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

View File

@@ -249,7 +249,7 @@ public:
NSString *cachePath = cacheURL ? cacheURL.path : @"";
_mbglFileSource = new mbgl::DefaultFileSource(cachePath.UTF8String, [[[[NSBundle mainBundle] resourceURL] path] UTF8String]);
_mbglMap = new mbgl::Map(*_mbglView, *_mbglFileSource, mbgl::MapMode::Continuous);
_mbglMap = new mbgl::Map(*_mbglView, *_mbglFileSource, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None);
// Install the OpenGL layer. Interface Builder’s synchronous drawing means
// we can’t display a map, so don’t even bother to have a map layer.
@@ -559,19 +559,24 @@ public:
}
- (void)viewDidMoveToWindow {
if (self.dormant && self.window) {
NSWindow *window = self.window;
if (self.dormant && window) {
_mbglMap->resume();
self.dormant = NO;
}
[self.window addObserver:self
forKeyPath:@"contentLayoutRect"
options:NSKeyValueObservingOptionInitial
context:NULL];
[self.window addObserver:self
forKeyPath:@"titlebarAppearsTransparent"
options:NSKeyValueObservingOptionInitial
context:NULL];
if (window && _mbglMap->getConstrainMode() == mbgl::ConstrainMode::None) {
_mbglMap->setConstrainMode(mbgl::ConstrainMode::HeightOnly);
}
[window addObserver:self
forKeyPath:@"contentLayoutRect"
options:NSKeyValueObservingOptionInitial
context:NULL];
[window addObserver:self
forKeyPath:@"titlebarAppearsTransparent"
options:NSKeyValueObservingOptionInitial
context:NULL];
}
- (BOOL)wantsLayer {

View File

@@ -395,6 +395,16 @@ NorthOrientation Map::getNorthOrientation() const {
return transform->getNorthOrientation();
}
#pragma mark - Constrain mode
void Map::setConstrainMode(mbgl::ConstrainMode mode) {
transform->setConstrainMode(mode);
update(Update::Repaint);
}
ConstrainMode Map::getConstrainMode() const {
return transform->getConstrainMode();
}
#pragma mark - Projection

View File

@@ -560,6 +560,17 @@ NorthOrientation Transform::getNorthOrientation() const {
return state.getNorthOrientation();
}
#pragma mark - Constrain mode
void Transform::setConstrainMode(mbgl::ConstrainMode mode) {
state.constrainMode = mode;
state.constrain(state.scale, state.x, state.y);
}
ConstrainMode Transform::getConstrainMode() const {
return state.getConstrainMode();
}
#pragma mark - Transition
void Transform::startTransition(const CameraOptions& camera,

View File

@@ -119,6 +119,10 @@ public:
// North Orientation
void setNorthOrientation(NorthOrientation);
NorthOrientation getNorthOrientation() const;
// Constrain mode
void setConstrainMode(ConstrainMode);
ConstrainMode getConstrainMode() const;
// Transitions
bool inTransition() const;

View File

@@ -94,6 +94,12 @@ double TransformState::getNorthOrientationAngle() const {
return angleOrientation;
}
#pragma mark - Constrain mode
ConstrainMode TransformState::getConstrainMode() const {
return constrainMode;
}
#pragma mark - Position
LatLng TransformState::getLatLng() const {
@@ -367,8 +373,10 @@ void TransformState::constrain(double& scale_, double& x_, double& y_) const {
x_ = std::max(-max_x, std::min(x_, max_x));
}
double max_y = (scale_ * util::tileSize - (rotatedNorth() ? width : height)) / 2;
y_ = std::max(-max_y, std::min(y_, max_y));
if (constrainMode != ConstrainMode::None) {
double max_y = (scale_ * util::tileSize - (rotatedNorth() ? width : height)) / 2;
y_ = std::max(-max_y, std::min(y_, max_y));
}
}
void TransformState::moveLatLng(const LatLng& latLng, const PrecisionPoint& anchor) {

View File

@@ -36,6 +36,9 @@ public:
// North Orientation
NorthOrientation getNorthOrientation() const;
double getNorthOrientationAngle() const;
// Constrain mode
ConstrainMode getConstrainMode() const;
// Position
LatLng getLatLng() const;