Mapbox iOS中flyToCamera自动返回初始位置问题求助
解决Mapbox iOS中flyToCamera执行后地图自动回退的问题
我之前也碰到过Mapbox iOS SDK里这个诡异的行为!你描述的情况——调用flyToCamera后地图先跳到目标相机位置,紧接着又自动弹回之前的位置,只有手动轻微拖拽地图后,这个方法才能正常工作——大概率是地图的用户位置跟踪功能和相机动画冲突导致的。
问题根源分析
当你的MGLMapView开启了用户位置跟踪(比如设置了showsUserLocation = YES,或者通过setUserTrackingMode:开启了自动定位),在你调用flyToCamera执行动画时,位置跟踪的回调(比如mapView:didUpdateUserLocation:)可能在动画结束后,自动将地图拉回用户当前的位置。而手动拖拽地图会触发Mapbox的内部逻辑,自动将userTrackingMode切换为MGLUserTrackingModeNone,所以后续再调用flyToCamera就不会有冲突了。
解决方案
这里有两个靠谱的解决思路,你可以根据自己的业务需求选择:
方案一:临时关闭位置跟踪再执行动画
在执行飞行动画前,先保存当前的位置跟踪模式,临时关闭跟踪,动画完成后再恢复原来的状态:
- (void) goToSomeCity { // 保存当前的用户位置跟踪模式 MGLUserTrackingMode originalTrackingMode = self.mapView.userTrackingMode; // 临时关闭位置跟踪,避免干扰动画 [self.mapView setUserTrackingMode:MGLUserTrackingModeNone animated:NO]; CLLocationCoordinate2D city = CLLocationCoordinate2DMake(34.0522,-118.2437); MGLMapCamera *targetCamera = [MGLMapCamera cameraLookingAtCenterCoordinate:city fromEyeCoordinate:self.mapView.userLocation.coordinate eyeAltitude:5000]; // 执行飞行动画,完成后恢复原跟踪模式 [self.mapView flyToCamera:targetCamera duration:2.0 completionHandler:^(BOOL finished) { if (originalTrackingMode != MGLUserTrackingModeNone) { [self.mapView setUserTrackingMode:originalTrackingMode animated:YES]; } }]; }
方案二:给位置跟踪回调加判断标记
如果你需要持续监听用户位置,但又不想在主动跳转地图时被干扰,可以添加一个标记变量,区分主动跳转和自动定位的场景:
// 先在类里添加一个标记属性 @property (nonatomic, assign) BOOL isInitiatedByUserAction; // 用户位置更新的回调 - (void)mapView:(MGLMapView *)mapView didUpdateUserLocation:(nullable MGLUserLocation *)userLocation { // 只有非主动触发的场景下,才自动定位到用户位置 if (!self.isInitiatedByUserAction && userLocation.coordinate.latitude != 0 && userLocation.coordinate.longitude != 0) { [mapView setCenterCoordinate:userLocation.coordinate animated:YES]; } } // 修改你的goToSomeCity方法 - (void) goToSomeCity { self.isInitiatedByUserAction = YES; CLLocationCoordinate2D city = CLLocationCoordinate2DMake(34.0522,-118.2437); MGLMapCamera *targetCamera = [MGLMapCamera cameraLookingAtCenterCoordinate:city fromEyeCoordinate:self.mapView.userLocation.coordinate eyeAltitude:5000]; [self.mapView flyToCamera:targetCamera duration:2.0 completionHandler:^(BOOL finished) { // 动画完成后重置标记 self.isInitiatedByUserAction = NO; }]; }
快速验证方法
你可以先做个简单测试:在调用flyToCamera之前,手动设置self.mapView.userTrackingMode = MGLUserTrackingModeNone,如果此时地图不再回退,那就完全可以确定是位置跟踪和动画的冲突问题了。
内容的提问来源于stack exchange,提问作者Lawrence Lin Murata
相关产品推荐
相关产品推荐

