-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[ios] Add delegate method to specify the user location annotation’s position #12907
Conversation
platform/ios/src/MGLMapView.h
Outdated
@@ -416,7 +416,7 @@ MGL_EXPORT IB_DESIGNABLE | |||
transition. If you don’t want to animate the change, use the | |||
`-setUserLocationVerticalAlignment:animated:` method instead. | |||
*/ | |||
@property (nonatomic, assign) MGLAnnotationVerticalAlignment userLocationVerticalAlignment; | |||
@property (nonatomic, assign) MGLAnnotationVerticalAlignment userLocationVerticalAlignment __attribute__((deprecated("Use -userLocationAnchorForMapView delegate method instead."))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Qualify the method name with the protocol name for discoverability.
|
||
@param mapView The map view that is tracking the user's location. | ||
*/ | ||
- (CGPoint)userLocationAnchorForMapView:(MGLMapView *)mapView; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By convention, the first selector part begins with the first parameter’s type. If the return type is a CGPoint
, describe it as an “anchor point” rather than an “anchor”, which typically describes an NSLayoutAnchor. Thus: -mapViewUserLocationAnchor:
.
@@ -308,6 +308,17 @@ NS_ASSUME_NONNULL_BEGIN | |||
*/ | |||
- (void)mapView:(MGLMapView *)mapView didChangeUserTrackingMode:(MGLUserTrackingMode)mode animated:(BOOL)animated; | |||
|
|||
/** | |||
Returns a CGPoint value to offset the user location annotation, relative to | |||
the camera's center coordinate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A screen point can only be relative to another screen point, not a geographic coordinate. I think the intention is to say that it’s relative to the center of the map view. Note that the navigation SDK’s analogous NavigationMapViewDelegate.navigationMapViewUserAnchorPoint(_:)
method is expressed relative to the map view’s origin, not its center. There are pros and cons to either approach, so it’s good that the frame of reference is being called out here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A screen point can only be relative to another screen point, not a geographic coordinate.
Does this mean the camera's center can also relate to a CGPoint instead of a coordinate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'm going to base my implementation off of the map view's origin as well, to keep things consistent with the implementation in the Navigation SDK.
platform/ios/src/MGLMapView.mm
Outdated
{ | ||
// Get whatever value is returned from the delegate method that responds to | ||
// the selector and assign it to the center | ||
center = [self.delegate userLocationAnchorForMapView:self]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line sets center
from scratch, effectively making it relative to the origin rather than the view’s center, which is stored in center
up to this point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we choose to set the anchor point based off the the origin, should we adjust the original center (CGPointMake(CGRectGetMidX(contentFrame), CGRectGetMidY(contentFrame))
) to do the same?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, because the legacy userLocationVerticalAlignment
code depends on that initial value, whereas the new -mapViewUserLocationAnchorPoint:
code does not.
platform/ios/src/MGLMapView.mm
Outdated
|
||
if ([self.delegate respondsToSelector:@selector(mapViewUserLocationAnchorPoint:)]) | ||
{ | ||
center = [self.delegate mapViewUserLocationAnchorPoint:self]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The delegate should be expressing the anchor point in relation to the content frame, so offset the anchor point by the content insets.
platform/ios/src/MGLMapView.mm
Outdated
{ | ||
// Get whatever value is returned from the delegate method that responds to | ||
// the selector and assign it to the center | ||
center = [self.delegate userLocationAnchorForMapView:self]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, because the legacy userLocationVerticalAlignment
code depends on that initial value, whereas the new -mapViewUserLocationAnchorPoint:
code does not.
@@ -310,7 +310,7 @@ NS_ASSUME_NONNULL_BEGIN | |||
|
|||
/** | |||
Returns a CGPoint value to offset the user location annotation, relative to | |||
the the map view's origin. | |||
the the map view's content insets. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
relative to the map view’s origin after applying the map view’s content insets.
platform/ios/src/MGLMapView.mm
Outdated
@@ -5997,7 +5997,8 @@ - (CGPoint)userLocationAnnotationViewCenter | |||
|
|||
if ([self.delegate respondsToSelector:@selector(mapViewUserLocationAnchorPoint:)]) | |||
{ | |||
center = [self.delegate mapViewUserLocationAnchorPoint:self]; | |||
CGPoint anchorPoint = [self.delegate mapViewUserLocationAnchorPoint:self]; | |||
center = CGPointMake((contentFrame.origin.x + anchorPoint.x), (contentFrame.origin.y + anchorPoint.y)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By this point, contentFrame
has already been inset by -edgePaddingForFollowingWithCourse
, which might not be quite correct. That method does account for the size of the puck, which is probably a good thing, but it also applies MGLUserLocationAnnotationViewInset
.
An idea for an integration test:
|
eb690a0
to
53b6b47
Compare
I think this is ready for a preliminary review 👀 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a branch where I can check this out in iosapp
?
|
||
@synthesize delegate; | ||
|
||
- (instancetype)init |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This init
method isn't needed here since it doesn't do anything in addition to super
.
return self; | ||
} | ||
|
||
- (CLAuthorizationStatus)authorizationStatus { return [CLLocationManager authorizationStatus]; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is a test manager, how about returning kCLAuthorizationStatusAuthorized
here?
d6be976
to
664a3ba
Compare
@julianrex Here's a branch you can use to test this out in iosapp: https://github.com/mapbox/mapbox-gl-native/tree/user-location-delegate-demo |
664a3ba
to
e267524
Compare
e267524
to
6dc7d5b
Compare
Rebased on master & added changelog entry. |
@@ -308,6 +308,17 @@ NS_ASSUME_NONNULL_BEGIN | |||
*/ | |||
- (void)mapView:(MGLMapView *)mapView didChangeUserTrackingMode:(MGLUserTrackingMode)mode animated:(BOOL)animated; | |||
|
|||
/** | |||
Returns a CGPoint value to offset the user location annotation, relative to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CGPoint
is already present in the declaration, so I’d maybe describe it here in lay terms. It’s an absolute screen coordinate, not an offset (which would be CGVector
):
Returns a screen coordinate at which to position the user location annotation…
map view’s origin after applying the map view’s content insets. | ||
|
||
This method will offset the user location annotation by the specified | ||
X and Y values determined by the CGPoint. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the default behavior when this method goes unimplemented? How does this method interact with the MGLMapView.userLocationVerticalAlignment
property when it is set and this method is also implemented?
platform/ios/CHANGELOG.md
Outdated
@@ -11,6 +11,11 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT | |||
* Fixed a crash when a style layer `*-pattern` property evaluates to nil for a particular feature. ([#12896](https://github.com/mapbox/mapbox-gl-native/pull/12896)) | |||
* Fixed an issue with view annotations (including the user location annotation) and the GL map lagging relative to each other. ([#12895](https://github.com/mapbox/mapbox-gl-native/pull/12895)) | |||
|
|||
### User location | |||
* Added `-[MGLMapViewDelegate mapViewUserLocationAnchorPoint:]` to offset the user location annotation with a custom `CGPoint`. ([#12907](https://github.com/mapbox/mapbox-gl-native/pull/12907)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…to customize the location of the user location annotation.
platform/ios/CHANGELOG.md
Outdated
### User location | ||
* Added `-[MGLMapViewDelegate mapViewUserLocationAnchorPoint:]` to offset the user location annotation with a custom `CGPoint`. ([#12907](https://github.com/mapbox/mapbox-gl-native/pull/12907)) | ||
* Marked `-[MGLMapView setUserLocationVerticalAlignment:]` as deprecated. Use `-[MGLMapViewDelegate mapViewUserLocationAnchorPoint:]` instead. ([#12907](https://github.com/mapbox/mapbox-gl-native/pull/12907)) | ||
* Added `-[MGLMapView updateUserLocationAnnotationView]` and `-[MGLMapView updateUserLocationAnnotationView:animated:]` to public API to update the position of the user location annotation. ([#12907](https://github.com/mapbox/mapbox-gl-native/pull/12907)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as the user is concerned, these methods never existed in the first place, so “to public API” is redundant.
Added the
-[MGLMapView updateUserLocationAnnotationView]
and-[MGLMapView updateUserLocationAnnotationView:animated:]
methods to update the position of the user location annotation between location updates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to merge once the documentation feedback in #12907 (review) is addressed.
…osition Update method name More API drafting Add deprecation flag Add Swift delegate integration test Update method name and documentation Update deprecation notices Update method name Offset anchor point relative to contentFrame Update docs Only run through switch statement if delegate is unimplemented Account for content inset + refactor logic Adjust edgePaddingForFollowing Fix Swift delegate integration test Set up integration test Set up test location manager . Remove unused file reference from test Return CGPoint value from delegate method within integration test setup Test anchor points Make updateUserLocationAnnotationView public Refactor test Update test location manager Changelog entry Doc fixes
6dc7d5b
to
db1d530
Compare
* Added `-[MGLMapViewDelegate mapViewUserLocationAnchorPoint:]` to customize the position of the user location annotation.. ([#12907](https://github.com/mapbox/mapbox-gl-native/pull/12907)) | ||
* Marked `-[MGLMapView setUserLocationVerticalAlignment:]` as deprecated. Use `-[MGLMapViewDelegate mapViewUserLocationAnchorPoint:]` instead. ([#12907](https://github.com/mapbox/mapbox-gl-native/pull/12907)) | ||
* Added the `-[MGLMapView updateUserLocationAnnotationView]` and `-[MGLMapView updateUserLocationAnnotationView:animated:]` methods to update the position of the user location annotation between location updates. ([#12907](https://github.com/mapbox/mapbox-gl-native/pull/12907)) | ||
* Fixed an issue where the user location annotation was positioned incorrectly when the map view had a left or right content inset. ([#12907](https://github.com/mapbox/mapbox-gl-native/pull/12907)) inset |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There’s an extra “inset” at the end of this sentence.
This PR makes three changes:
-[MGLMapView setUserLocationVerticalAlignment:]
and the associatedMGLAnnotationVerticalAlignment
enumeration.-[MGLMapView updateUserLocationAnnotationView]
and-[MGLMapView updateUserLocationAnnotationView:animated:]
to programmatically force the user location annotation to update.