add the ability to have ios camera animation durations dynamic during navigation (#3568)

This commit is contained in:
yousifd
2025-07-16 12:08:07 +03:00
committed by GitHub
parent aeb1283614
commit 3adf431b19
2 changed files with 30 additions and 10 deletions

View File

@@ -550,6 +550,15 @@ MLN_EXPORT
*/
@property (nonatomic, assign) BOOL showsUserLocation;
/**
A boolean value indicating whether camera animation duration is set based
on the time difference between the last location update and the current one
or the default animation duration of 1 second.
The default value of this property is `NO`
*/
@property (nonatomic, assign) BOOL dynamicNavigationCameraAnimationDuration;
/**
A Boolean value indicating whether the map may request authorization to use location services.

View File

@@ -951,6 +951,8 @@ public:
_targetCoordinate = kCLLocationCoordinate2DInvalid;
_shouldRequestAuthorizationToUseLocationServices = YES;
_dynamicNavigationCameraAnimationDuration = NO;
}
- (mbgl::Size)size
@@ -6317,14 +6319,18 @@ static void *windowScreenContext = &windowScreenContext;
}
}
[self didUpdateLocationWithUserTrackingAnimated:animated completionHandler:completion];
NSTimeInterval duration = MLNAnimationDuration;
NSTimeInterval userLocationDuration = MLNAnimationDuration;
if (oldLocation && ! CGPointEqualToPoint(self.userLocationAnnotationView.center, CGPointZero))
{
duration = MIN([newLocation.timestamp timeIntervalSinceDate:oldLocation.timestamp], MLNUserLocationAnimationDuration);
userLocationDuration = MIN([newLocation.timestamp timeIntervalSinceDate:oldLocation.timestamp], MLNUserLocationAnimationDuration);
}
[self updateUserLocationAnnotationViewAnimatedWithDuration:duration];
[self updateUserLocationAnnotationViewAnimatedWithDuration:userLocationDuration];
NSTimeInterval cameraDuration = MLNUserLocationAnimationDuration;
if (self.dynamicNavigationCameraAnimationDuration && oldLocation) {
cameraDuration = MIN([newLocation.timestamp timeIntervalSinceDate:oldLocation.timestamp], MLNUserLocationAnimationDuration);
}
[self didUpdateLocationWithUserTrackingDuration:cameraDuration completionHandler:completion];
if (self.userTrackingMode == MLNUserTrackingModeNone &&
self.userLocationAnnotationView.accessibilityElementIsFocused &&
@@ -6335,6 +6341,11 @@ static void *windowScreenContext = &windowScreenContext;
}
- (void)didUpdateLocationWithUserTrackingAnimated:(BOOL)animated completionHandler:(nullable void (^)(void))completion
{
[self didUpdateLocationWithUserTrackingDuration:animated ? MLNUserLocationAnimationDuration : 0 completionHandler:completion];
}
- (void)didUpdateLocationWithUserTrackingDuration:(NSTimeInterval)duration completionHandler:(nullable void (^)(void))completion
{
CLLocation *location = self.userLocation.location;
if ( ! _showsUserLocation || ! location
@@ -6369,31 +6380,31 @@ static void *windowScreenContext = &windowScreenContext;
if (self.userTrackingState != MLNUserTrackingStateBegan)
{
// Keep both the user and the destination in view.
[self didUpdateLocationWithTargetAnimated:animated completionHandler:completion];
[self didUpdateLocationWithTargetAnimated:duration != 0 completionHandler:completion];
}
}
else if (self.userTrackingState == MLNUserTrackingStatePossible)
{
// The first location update is often a great distance away from the
// current viewport, so fly there to provide additional context.
[self didUpdateLocationSignificantlyAnimated:animated completionHandler:completion];
[self didUpdateLocationSignificantlyAnimated:duration != 0 completionHandler:completion];
}
else if (self.userTrackingState == MLNUserTrackingStateChanged)
{
// Subsequent updates get a more subtle animation.
[self didUpdateLocationIncrementallyAnimated:animated completionHandler:completion];
[self didUpdateLocationIncrementallyDuration:duration completionHandler:completion];
}
[self unrotateIfNeededAnimated:YES];
}
/// Changes the viewport based on an incremental location update.
- (void)didUpdateLocationIncrementallyAnimated:(BOOL)animated completionHandler:(nullable void (^)(void))completion
- (void)didUpdateLocationIncrementallyDuration:(NSTimeInterval)duration completionHandler:(nullable void (^)(void))completion
{
[self _setCenterCoordinate:self.userLocation.location.coordinate
edgePadding:self.edgePaddingForFollowing
zoomLevel:self.zoomLevel
direction:self.directionByFollowingWithCourse
duration:animated ? MLNUserLocationAnimationDuration : 0
duration:duration
animationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]
completionHandler:completion];
}