SwiftUI MapKit Polyline无法跟随用户移动实时更新问题求助
路径无法实时更新的核心原因是数据变更没有触发UI刷新,结合代码的具体问题和修改方案如下:
核心问题根因
- 数据变更未通知UI:
LocationsModel中存储位置的locationArray未添加@Published修饰符,数组内容更新时SwiftUI无法感知,不会触发地图组件重绘,只有重新进入页面初始化时才会读取最新数据生成路径。 - 旧路径移除逻辑错误:
updateUIView中每次新建MKPolyline实例调用删除方法,该实例和已添加到地图上的旧路径实例不是同一个对象,无法成功删除旧路径,多次叠加会导致绘制异常。 - 地图模式冲突:代码同时开启了用户位置自动跟随模式和手动设置地图区域逻辑,两者互相冲突导致地图区域无法自动跟随用户移动。
- 重复设置代理:
MKMapView的代理被放在updateUIView中每次刷新都重复赋值,属于不必要操作。
修改步骤
1. 修正LocationsModel属性定义
给存储位置的数组添加@Published修饰,让数据变更时自动通知订阅的View刷新:
class LocationsModel: ObservableObject { // 添加@Published修饰符 @Published var locationArray: [CLLocation] = [] // 其余原有属性保持不变 var speeds: [Double] = [] var altitude: [Double] = [] var coordArray: [CLLocationCoordinate2D] = [] // 原有coordinates2D计算属性保持不变 var coordinates2D:[CLLocationCoordinate2D] { var coordArray = [CLLocationCoordinate2D]() for c in locationArray { coordArray.append(CLLocationCoordinate2D(latitude: c.coordinate.latitude, longitude: c.coordinate.longitude)) } return coordArray } // ... 其余原有代码 }
2. 修复路径更新逻辑
修改SecondMap中的updateUIView方法,删除冲突的手动设置区域代码,修正旧路径移除逻辑:
func updateUIView(_ uiView: MKMapView, context: Context) { // 移除手动设置region的代码,避免和userTrackingMode冲突 // 先删除所有已存在的Polyline覆盖层 uiView.overlays.forEach { overlay in if overlay is MKPolyline { uiView.removeOverlay(overlay) } } // 添加最新的路径 let polyline = MKPolyline(coordinates: model.coordinates2D, count: model.coordinates2D.count) uiView.addOverlay(polyline) }
3. 调整代理设置位置
把代理赋值移到初始化方法中,只执行一次:
func makeUIView(context: Context) -> MKMapView { let mapView = MKMapView() mapView.showsUserLocation = true mapView.userTrackingMode = .followWithHeading // 移到此处设置代理 mapView.delegate = context.coordinator return mapView }
4. 优化位置更新回调逻辑(可选)
原代码中速度和海拔数组追加时会重复添加所有历史数据,修正为仅追加新位置的对应值:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { for newLocation in locations { let howRecent = newLocation.timestamp.timeIntervalSinceNow guard newLocation.horizontalAccuracy < 20 && abs(howRecent) < 10 else { continue } // 修正为仅添加新位置的速度和海拔 speeds.append(newLocation.speed) altitude.append(newLocation.altitude) locationArray.append(newLocation) } }
内容的提问来源于stack exchange,提问作者Dilts
相关产品推荐
相关产品推荐

