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

Commit

Permalink
[ios] Account for top/bottom bars
Browse files Browse the repository at this point in the history
  • Loading branch information
1ec5 committed Jan 17, 2016
1 parent c5c09dd commit 4aeb79e
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Known issues:
- Tapping now selects annotations more reliably. Tapping near the top of a large annotation image now selects that annotation. An annotation image’s alignment insets influence how far away the user can tap and still select the annotation. For example, if your annotation image has a large shadow, you can keep that shadow from being tappable by excluding it from the image’s alignment rect. ([#3261](https://github.com/mapbox/mapbox-gl-native/pull/3261))
- A new method on MGLMapView, `-flyToCamera:withDuration:completionHandler:`, lets you transition between viewpoints along an arc as if by aircraft. ([#3171](https://github.com/mapbox/mapbox-gl-native/pull/3171), [#3301](https://github.com/mapbox/mapbox-gl-native/pull/3301))
- MGLMapCamera’s `altitude` values now match those of MKMapCamera. ([#3362](https://github.com/mapbox/mapbox-gl-native/pull/3362))
- MGLMapView properties like `centerCoordinate` and `camera` now offset the center to account for any translucent top or bottom bar. As a result, when user tracking is enabled and the map view is an immediate child of a view controller, the user dot is centered in the unobscured portion of the map view. To override this offset, modify the `contentInset` property; you may also need to set the containing view controller’s `automaticallyAdjustsScrollViewInsets` property to `NO`. ([#3583](https://github.com/mapbox/mapbox-gl-native/pull/3583))
- The user dot’s callout view is now centered above the user dot. It was previously offset slightly to the left. ([#3261](https://github.com/mapbox/mapbox-gl-native/pull/3261))
- Fixed an issue with small map views not properly fitting annotations within bounds. (#[3407](https://github.com/mapbox/mapbox-gl-native/pull/3407))
- The map will now snap to north. ([#3403](https://github.com/mapbox/mapbox-gl-native/pull/3403))
Expand Down
16 changes: 16 additions & 0 deletions include/mbgl/ios/MGLMapView.h
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,22 @@ IB_DESIGNABLE
*/
- (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration peakAltitude:(CLLocationDistance)peakAltitude completionHandler:(nullable void (^)(void))completion;

/**
The distance from the edges of the map view’s frame to the edges of the map
view’s logical viewport.
When the value of this property is equal to `UIEdgeInsetsZero`, viewport
properties such as `centerCoordinate` assume a viewport that matches the map
view’s frame. Otherwise, those properties are inset, excluding part of the
frame from the viewport. For instance, if the only the top edge is inset, the
map center is effectively shifted downward.
When the map view’s superview is an instance of `UIViewController` whose
`automaticallyAdjustsScrollViewInsets` property is `YES`, the value of this
property may be overridden at any time.
*/
@property (nonatomic, assign) UIEdgeInsets contentInset;

#pragma mark Converting Geographic Coordinates

/**
Expand Down
65 changes: 59 additions & 6 deletions platform/ios/src/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -410,13 +410,15 @@ - (void)commonInit
//
mbgl::CameraOptions options;
options.center = mbgl::LatLng(0, 0);
mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(self.contentInset);
options.padding = padding;
options.zoom = _mbglMap->getMinZoom();
_mbglMap->jumpTo(options);
_pendingLatitude = NAN;
_pendingLongitude = NAN;

// metrics: map load event
mbgl::LatLng latLng = _mbglMap->getLatLng();
mbgl::LatLng latLng = _mbglMap->getLatLng(padding);
int zoom = round(_mbglMap->getZoom());

[MGLMapboxEvents pushEvent:MGLEventTypeMapLoad withAttributes:@{
Expand Down Expand Up @@ -747,6 +749,8 @@ - (void)glkView:(__unused GLKView *)view drawInRect:(__unused CGRect)rect
- (void)layoutSubviews
{
[super layoutSubviews];

[self adjustContentInset];

if ( ! _isTargetingInterfaceBuilder)
{
Expand All @@ -766,6 +770,49 @@ - (void)layoutSubviews
}
}

/// Updates `contentInset` to reflect the current window geometry.
- (void)adjustContentInset
{
// We could crawl all the way up the responder chain using
// -viewControllerForLayoutGuides, but an intervening view means that any
// manual contentInset should not be overridden; something other than the
// top and bottom bars may be influencing the manual inset.
UIViewController *viewController;
if ([self.nextResponder isKindOfClass:[UIViewController class]])
{
// This map view is the content view of a view controller.
viewController = (UIViewController *)self.nextResponder;
}
else if ([self.superview.nextResponder isKindOfClass:[UIViewController class]])
{
// This map view is an immediate child of a view controller’s content view.
viewController = (UIViewController *)self.superview.nextResponder;
}

if ( ! viewController.automaticallyAdjustsScrollViewInsets)
{
return;
}

UIEdgeInsets contentInsets = UIEdgeInsetsZero;
CGPoint topPoint = CGPointMake(0, viewController.topLayoutGuide.length);
contentInsets.top = [self convertPoint:topPoint fromView:viewController.view].y;
CGPoint bottomPoint = CGPointMake(0, CGRectGetMaxY(viewController.view.bounds)
- viewController.bottomLayoutGuide.length);
contentInsets.bottom = (CGRectGetMaxY(self.bounds) - [self convertPoint:bottomPoint
fromView:viewController.view].y);

if ( ! UIEdgeInsetsEqualToEdgeInsets(contentInsets, self.contentInset))
{
// After adjusting the content insets, move the center coordinate from
// the old frame of reference to the new one represented by the newly
// set content insets.
CLLocationCoordinate2D oldCenter = self.centerCoordinate;
self.contentInset = contentInsets;
self.centerCoordinate = oldCenter;
}
}

#pragma mark - Life Cycle -

- (void)updateFromDisplayLink
Expand Down Expand Up @@ -1585,7 +1632,8 @@ - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate

- (CLLocationCoordinate2D)centerCoordinate
{
return MGLLocationCoordinate2DFromLatLng(_mbglMap->getLatLng());
mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(self.contentInset);
return MGLLocationCoordinate2DFromLatLng(_mbglMap->getLatLng(padding));
}

- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(double)zoomLevel animated:(BOOL)animated
Expand All @@ -1610,6 +1658,7 @@ - (void)_setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:

mbgl::CameraOptions cameraOptions;
cameraOptions.center = MGLLatLngFromLocationCoordinate2D(centerCoordinate);
cameraOptions.padding = MGLEdgeInsetsFromNSEdgeInsets(self.contentInset);
cameraOptions.zoom = fmaxf(zoomLevel, self.currentMinimumZoom);
if (direction >= 0)
{
Expand Down Expand Up @@ -1723,15 +1772,16 @@ - (void)setVisibleCoordinates:(CLLocationCoordinate2D *)coordinates count:(NSUIn

// NOTE: does not disrupt tracking mode
[self willChangeValueForKey:@"visibleCoordinateBounds"];
mbgl::EdgeInsets mbglInsets = MGLEdgeInsetsFromNSEdgeInsets(insets);
mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(insets);
padding += MGLEdgeInsetsFromNSEdgeInsets(self.contentInset);
mbgl::AnnotationSegment segment;
segment.reserve(count);
for (NSUInteger i = 0; i < count; i++)
{
segment.push_back({coordinates[i].latitude, coordinates[i].longitude});
}

mbgl::CameraOptions cameraOptions = _mbglMap->cameraForLatLngs(segment, mbglInsets);
mbgl::CameraOptions cameraOptions = _mbglMap->cameraForLatLngs(segment, padding);
if (direction >= 0)
{
cameraOptions.angle = MGLRadiansFromDegrees(-direction);
Expand Down Expand Up @@ -1787,7 +1837,9 @@ - (void)_setDirection:(CLLocationDirection)direction animated:(BOOL)animated

CGFloat duration = animated ? MGLAnimationDuration : 0;

_mbglMap->setBearing(direction, MGLDurationInSeconds(duration));
_mbglMap->setBearing(direction,
MGLEdgeInsetsFromNSEdgeInsets(self.contentInset),
MGLDurationInSeconds(duration));
}

- (void)setDirection:(CLLocationDirection)direction
Expand Down Expand Up @@ -1912,6 +1964,7 @@ - (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration
{
mbgl::CameraOptions options;
options.center = MGLLatLngFromLocationCoordinate2D(camera.centerCoordinate);
options.padding = MGLEdgeInsetsFromNSEdgeInsets(self.contentInset);
options.zoom = MGLZoomLevelForAltitude(camera.altitude, camera.pitch,
camera.centerCoordinate.latitude,
self.frame.size);
Expand Down Expand Up @@ -2973,7 +3026,7 @@ - (void)locationManager:(__unused CLLocationManager *)manager didUpdateLocations
{
// center on user location unless we're already centered there (or very close)
//
CGPoint mapCenterPoint = [self convertPoint:self.center fromView:self.superview];
CGPoint mapCenterPoint = [self convertCoordinate:self.centerCoordinate toPointToView:self];
CGPoint userLocationPoint = [self convertCoordinate:self.userLocation.coordinate toPointToView:self];

if (std::abs(userLocationPoint.x - mapCenterPoint.x) > 1.0 || std::abs(userLocationPoint.y - mapCenterPoint.y) > 1.0)
Expand Down

0 comments on commit 4aeb79e

Please sign in to comment.