expo-gaode-map 1.1.4 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ios/ExpoGaodeMapModule.swift +0 -4
- package/ios/ExpoGaodeMapView.swift +34 -18
- package/ios/managers/OverlayManager.swift +0 -6
- package/ios/overlays/CircleView.swift +0 -3
- package/ios/overlays/ClusterViewModule.swift +0 -2
- package/ios/overlays/MarkerView.swift +158 -56
- package/ios/overlays/MultiPointViewModule.swift +0 -2
- package/ios/overlays/PolygonView.swift +2 -12
- package/ios/overlays/PolylineView.swift +2 -12
- package/ios/utils/PermissionManager.swift +0 -1
- package/package.json +1 -1
|
@@ -266,16 +266,12 @@ public class ExpoGaodeMapModule: Module {
|
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
self.permissionManager?.requestPermission { granted, status in
|
|
269
|
-
print("🔐 [PermissionManager] 权限回调: granted=\(granted), status=\(status)")
|
|
270
|
-
|
|
271
269
|
// 无论结果如何,都延迟后再次检查最终状态
|
|
272
270
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
|
273
271
|
let finalStatus = CLLocationManager.authorizationStatus()
|
|
274
272
|
let finalGranted = finalStatus == .authorizedAlways || finalStatus == .authorizedWhenInUse
|
|
275
273
|
let finalStatusString = self.getAuthorizationStatusString(finalStatus)
|
|
276
274
|
|
|
277
|
-
print("🔐 [PermissionManager] 最终状态: granted=\(finalGranted), status=\(finalStatusString)")
|
|
278
|
-
|
|
279
275
|
promise.resolve([
|
|
280
276
|
"granted": finalGranted,
|
|
281
277
|
"status": finalStatusString
|
|
@@ -82,6 +82,8 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
|
|
|
82
82
|
private var isMapLoaded = false
|
|
83
83
|
/// 是否正在处理 annotation 选择事件
|
|
84
84
|
private var isHandlingAnnotationSelect = false
|
|
85
|
+
/// MarkerView 的隐藏容器(用于渲染 children)
|
|
86
|
+
private var markerContainer: UIView!
|
|
85
87
|
|
|
86
88
|
// MARK: - 初始化
|
|
87
89
|
|
|
@@ -92,11 +94,23 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
|
|
|
92
94
|
MAMapView.updatePrivacyAgree(.didAgree)
|
|
93
95
|
MAMapView.updatePrivacyShow(.didShow, privacyInfo: .didContain)
|
|
94
96
|
|
|
97
|
+
// 创建 MAMapView
|
|
95
98
|
mapView = MAMapView(frame: bounds)
|
|
99
|
+
|
|
96
100
|
mapView.delegate = self
|
|
97
101
|
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
98
102
|
|
|
99
|
-
//
|
|
103
|
+
// 创建 MarkerView 隐藏容器
|
|
104
|
+
markerContainer = UIView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
105
|
+
markerContainer.isHidden = true
|
|
106
|
+
markerContainer.isUserInteractionEnabled = false
|
|
107
|
+
markerContainer.alpha = 0
|
|
108
|
+
|
|
109
|
+
// 先添加隐藏容器(在最底层)
|
|
110
|
+
addSubview(markerContainer)
|
|
111
|
+
|
|
112
|
+
// 再添加 mapView(在隐藏容器之上,确保地图可以接收触摸)
|
|
113
|
+
addSubview(mapView)
|
|
100
114
|
|
|
101
115
|
cameraManager = CameraManager(mapView: mapView)
|
|
102
116
|
uiManager = UIManager(mapView: mapView)
|
|
@@ -139,7 +153,8 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
|
|
|
139
153
|
* 收集所有 MarkerView 子视图并设置地图
|
|
140
154
|
*/
|
|
141
155
|
private func collectAndSetupMarkerViews() {
|
|
142
|
-
|
|
156
|
+
// 从隐藏容器中收集 MarkerView
|
|
157
|
+
for subview in markerContainer.subviews {
|
|
143
158
|
if let markerView = subview as? MarkerView {
|
|
144
159
|
markerView.setMap(mapView)
|
|
145
160
|
}
|
|
@@ -152,11 +167,14 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
|
|
|
152
167
|
*/
|
|
153
168
|
override func addSubview(_ view: UIView) {
|
|
154
169
|
if let markerView = view as? MarkerView {
|
|
155
|
-
//
|
|
170
|
+
// ✅ 关键修复:将 MarkerView 添加到隐藏容器中,而不是主视图
|
|
171
|
+
// 这样 MarkerView 完全不会影响地图的触摸事件
|
|
172
|
+
markerContainer.addSubview(markerView)
|
|
156
173
|
markerView.setMap(mapView)
|
|
157
174
|
return
|
|
158
175
|
}
|
|
159
176
|
|
|
177
|
+
// 其他视图正常添加
|
|
160
178
|
super.addSubview(view)
|
|
161
179
|
|
|
162
180
|
if let circleView = view as? CircleView {
|
|
@@ -195,13 +213,9 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
|
|
|
195
213
|
func applyProps() {
|
|
196
214
|
uiManager.setMapType(mapType)
|
|
197
215
|
|
|
198
|
-
//
|
|
199
|
-
if let position = initialCameraPosition
|
|
216
|
+
// 如果有初始位置,设置相机位置
|
|
217
|
+
if let position = initialCameraPosition {
|
|
200
218
|
cameraManager.setInitialCameraPosition(position)
|
|
201
|
-
addSubview(mapView)
|
|
202
|
-
} else if mapView.superview == nil {
|
|
203
|
-
// 没有初始位置,直接添加地图
|
|
204
|
-
addSubview(mapView)
|
|
205
219
|
}
|
|
206
220
|
|
|
207
221
|
uiManager.setShowsScale(showsScale)
|
|
@@ -350,8 +364,8 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate {
|
|
|
350
364
|
* 析构函数 - 清理资源
|
|
351
365
|
*/
|
|
352
366
|
deinit {
|
|
367
|
+
// 先设置 delegate 为 nil,停止接收回调
|
|
353
368
|
mapView?.delegate = nil
|
|
354
|
-
overlayManager?.clear()
|
|
355
369
|
}
|
|
356
370
|
}
|
|
357
371
|
|
|
@@ -415,20 +429,14 @@ extension ExpoGaodeMapView {
|
|
|
415
429
|
*/
|
|
416
430
|
private func checkCirclePress(at coordinate: CLLocationCoordinate2D) -> Bool {
|
|
417
431
|
let circleViews = subviews.compactMap { $0 as? CircleView }
|
|
418
|
-
print("🔍 检查圆形点击 - 找到 \(circleViews.count) 个 CircleView")
|
|
419
432
|
|
|
420
433
|
for circleView in circleViews {
|
|
421
|
-
guard let circle = circleView.circle else {
|
|
422
|
-
print("⚠️ CircleView 没有 circle 对象")
|
|
423
|
-
continue
|
|
424
|
-
}
|
|
434
|
+
guard let circle = circleView.circle else { continue }
|
|
425
435
|
|
|
426
436
|
let circleCenter = circle.coordinate
|
|
427
437
|
let distance = calculateDistance(from: coordinate, to: circleCenter)
|
|
428
|
-
print("📍 圆心: (\(circleCenter.latitude), \(circleCenter.longitude)), 半径: \(circle.radius)m, 距离: \(distance)m")
|
|
429
438
|
|
|
430
439
|
if distance <= circle.radius {
|
|
431
|
-
print("✅ 点击在圆形内,触发 onPress")
|
|
432
440
|
circleView.onPress([
|
|
433
441
|
"latitude": coordinate.latitude,
|
|
434
442
|
"longitude": coordinate.longitude
|
|
@@ -436,7 +444,6 @@ extension ExpoGaodeMapView {
|
|
|
436
444
|
return true
|
|
437
445
|
}
|
|
438
446
|
}
|
|
439
|
-
print("❌ 点击不在任何圆形内")
|
|
440
447
|
return false
|
|
441
448
|
}
|
|
442
449
|
|
|
@@ -585,6 +592,15 @@ extension ExpoGaodeMapView {
|
|
|
585
592
|
}
|
|
586
593
|
|
|
587
594
|
if annotation.isKind(of: MAPointAnnotation.self) {
|
|
595
|
+
// 首先检查是否是声明式 MarkerView 的 annotation
|
|
596
|
+
// 从隐藏容器中查找 MarkerView
|
|
597
|
+
for subview in markerContainer.subviews {
|
|
598
|
+
if let markerView = subview as? MarkerView, markerView.annotation === annotation {
|
|
599
|
+
return markerView.getAnnotationView(for: mapView, annotation: annotation)
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// 如果不是声明式的,检查是否是命令式 API 的 Marker
|
|
588
604
|
guard let props = overlayManager.getMarkerProps(for: annotation) else {
|
|
589
605
|
return nil
|
|
590
606
|
}
|
|
@@ -320,20 +320,16 @@ class OverlayManager {
|
|
|
320
320
|
|
|
321
321
|
// 设置纹理或颜色
|
|
322
322
|
if let textureUrl = style?["texture"] as? String, !textureUrl.isEmpty {
|
|
323
|
-
print("🔷 OverlayManager: 加载纹理 \(textureUrl)")
|
|
324
323
|
loadPolylineTexture(url: textureUrl, renderer: renderer)
|
|
325
324
|
} else {
|
|
326
325
|
if let color = style?["color"] {
|
|
327
326
|
let parsedColor = ColorParser.parseColor(color)
|
|
328
327
|
renderer.strokeColor = parsedColor ?? .red
|
|
329
|
-
print("🔷 OverlayManager: color=\(color) -> \(String(describing: parsedColor))")
|
|
330
328
|
} else if let strokeColor = style?["strokeColor"] {
|
|
331
329
|
let parsedColor = ColorParser.parseColor(strokeColor)
|
|
332
330
|
renderer.strokeColor = parsedColor ?? .red
|
|
333
|
-
print("🔷 OverlayManager: strokeColor=\(strokeColor) -> \(String(describing: parsedColor))")
|
|
334
331
|
} else {
|
|
335
332
|
renderer.strokeColor = .red
|
|
336
|
-
print("🔷 OverlayManager: 使用默认红色")
|
|
337
333
|
}
|
|
338
334
|
}
|
|
339
335
|
|
|
@@ -343,8 +339,6 @@ class OverlayManager {
|
|
|
343
339
|
return nil
|
|
344
340
|
}
|
|
345
341
|
|
|
346
|
-
print("🔶 OverlayManager.getRenderer(Polygon): style=\(String(describing: style))")
|
|
347
|
-
|
|
348
342
|
// 设置填充颜色
|
|
349
343
|
if let fillColor = style?["fillColor"] {
|
|
350
344
|
let parsedColor = ColorParser.parseColor(fillColor)
|
|
@@ -119,7 +119,6 @@ class CircleView: ExpoView {
|
|
|
119
119
|
* @param color 颜色值
|
|
120
120
|
*/
|
|
121
121
|
func setFillColor(_ color: Any?) {
|
|
122
|
-
print("🔵 CircleView.setFillColor: \(String(describing: color))")
|
|
123
122
|
fillColor = color
|
|
124
123
|
renderer = nil
|
|
125
124
|
updateCircle()
|
|
@@ -130,7 +129,6 @@ class CircleView: ExpoView {
|
|
|
130
129
|
* @param color 颜色值
|
|
131
130
|
*/
|
|
132
131
|
func setStrokeColor(_ color: Any?) {
|
|
133
|
-
print("🔵 CircleView.setStrokeColor: \(String(describing: color))")
|
|
134
132
|
strokeColor = color
|
|
135
133
|
renderer = nil
|
|
136
134
|
updateCircle()
|
|
@@ -141,7 +139,6 @@ class CircleView: ExpoView {
|
|
|
141
139
|
* @param width 宽度值
|
|
142
140
|
*/
|
|
143
141
|
func setStrokeWidth(_ width: Float) {
|
|
144
|
-
print("🔵 CircleView.setStrokeWidth: \(width)")
|
|
145
142
|
strokeWidth = width
|
|
146
143
|
renderer = nil
|
|
147
144
|
updateCircle()
|
|
@@ -48,19 +48,43 @@ class MarkerView: ExpoView {
|
|
|
48
48
|
var pinColor: String = "red"
|
|
49
49
|
/// 是否显示气泡
|
|
50
50
|
var canShowCallout: Bool = true
|
|
51
|
-
///
|
|
52
|
-
private var mapView: MAMapView?
|
|
51
|
+
/// 地图视图弱引用(避免循环引用)
|
|
52
|
+
private weak var mapView: MAMapView?
|
|
53
53
|
/// 标记点对象
|
|
54
54
|
var annotation: MAPointAnnotation?
|
|
55
|
+
/// 标记是否正在被移除(防止重复移除)
|
|
56
|
+
private var isRemoving: Bool = false
|
|
55
57
|
/// 标记点视图
|
|
56
58
|
private var annotationView: MAAnnotationView?
|
|
57
59
|
/// 待处理的位置(在 setMap 之前设置)
|
|
58
60
|
private var pendingPosition: [String: Double]?
|
|
61
|
+
/// 延迟添加任务
|
|
62
|
+
private var pendingAddTask: DispatchWorkItem?
|
|
59
63
|
|
|
60
64
|
required init(appContext: AppContext? = nil) {
|
|
61
65
|
super.init(appContext: appContext)
|
|
62
|
-
//
|
|
66
|
+
// 完全禁用交互,让触摸事件穿透
|
|
63
67
|
isUserInteractionEnabled = false
|
|
68
|
+
// 关键:让所有子视图也不接收触摸事件
|
|
69
|
+
isMultipleTouchEnabled = false
|
|
70
|
+
isExclusiveTouch = false
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 重写 hitTest,让触摸事件完全穿透此视图
|
|
75
|
+
* 这是解决旧架构下 children 阻挡地图触摸的关键
|
|
76
|
+
*/
|
|
77
|
+
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
|
78
|
+
// 始终返回 nil,让触摸事件穿透到地图
|
|
79
|
+
return nil
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 重写 point(inside:with:),确保此视图不响应任何触摸
|
|
84
|
+
*/
|
|
85
|
+
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
|
86
|
+
// 始终返回 false,表示点击不在此视图内
|
|
87
|
+
return false
|
|
64
88
|
}
|
|
65
89
|
|
|
66
90
|
/**
|
|
@@ -89,9 +113,14 @@ class MarkerView: ExpoView {
|
|
|
89
113
|
return
|
|
90
114
|
}
|
|
91
115
|
|
|
92
|
-
//
|
|
116
|
+
// 取消之前的延迟任务
|
|
117
|
+
pendingAddTask?.cancel()
|
|
118
|
+
|
|
119
|
+
// 移除旧的标记(在主线程执行)
|
|
93
120
|
if let oldAnnotation = annotation {
|
|
94
|
-
|
|
121
|
+
DispatchQueue.main.async {
|
|
122
|
+
mapView.removeAnnotation(oldAnnotation)
|
|
123
|
+
}
|
|
95
124
|
}
|
|
96
125
|
|
|
97
126
|
// 创建新的标记
|
|
@@ -100,51 +129,59 @@ class MarkerView: ExpoView {
|
|
|
100
129
|
annotation.title = title
|
|
101
130
|
annotation.subtitle = markerDescription
|
|
102
131
|
|
|
103
|
-
mapView.addAnnotation(annotation)
|
|
104
132
|
self.annotation = annotation
|
|
105
133
|
|
|
106
|
-
//
|
|
107
|
-
|
|
108
|
-
guard let self = self else {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
guard let self = self else { return }
|
|
115
|
-
self.updateMarkerImage()
|
|
134
|
+
// 延迟添加到地图,等待 React Native 渲染 children
|
|
135
|
+
let task = DispatchWorkItem { [weak self] in
|
|
136
|
+
guard let self = self, !self.isRemoving else {
|
|
137
|
+
print("⚠️ [MarkerView] 延迟任务取消,isRemoving: \(self?.isRemoving ?? true)")
|
|
138
|
+
return
|
|
139
|
+
}
|
|
140
|
+
print("✅ [MarkerView] Annotation 延迟添加,当前 subviews: \(self.subviews.count)")
|
|
141
|
+
mapView.addAnnotation(annotation)
|
|
116
142
|
}
|
|
143
|
+
pendingAddTask = task
|
|
144
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: task)
|
|
117
145
|
}
|
|
118
146
|
|
|
119
147
|
/**
|
|
120
|
-
*
|
|
148
|
+
* 获取 annotation 视图(由 ExpoGaodeMapView 调用)
|
|
121
149
|
*/
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
150
|
+
func getAnnotationView(for mapView: MAMapView, annotation: MAAnnotation) -> MAAnnotationView? {
|
|
151
|
+
print("🎨 [MarkerView] getAnnotationView 被调用")
|
|
152
|
+
print("🎨 [MarkerView] subviews.count: \(self.subviews.count)")
|
|
153
|
+
|
|
154
|
+
let reuseId = "custom_marker_\(ObjectIdentifier(self).hashValue)"
|
|
155
|
+
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
|
|
156
|
+
|
|
157
|
+
if annotationView == nil {
|
|
158
|
+
annotationView = MAAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
|
|
159
|
+
annotationView?.canShowCallout = canShowCallout
|
|
160
|
+
annotationView?.isDraggable = draggable
|
|
128
161
|
}
|
|
129
162
|
|
|
130
|
-
|
|
163
|
+
annotationView?.annotation = annotation
|
|
164
|
+
self.annotationView = annotationView
|
|
131
165
|
|
|
166
|
+
// 设置图标
|
|
132
167
|
if self.subviews.count > 0 {
|
|
133
|
-
|
|
168
|
+
print("🎨 [MarkerView] 尝试创建自定义图片...")
|
|
134
169
|
if let image = self.createImageFromSubviews() {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
170
|
+
print("✅ [MarkerView] 自定义图片创建成功, size: \(image.size)")
|
|
171
|
+
annotationView?.image = image
|
|
172
|
+
annotationView?.centerOffset = CGPoint(x: 0, y: -image.size.height / 2)
|
|
138
173
|
} else {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
174
|
+
print("❌ [MarkerView] 自定义图片创建失败,使用默认图标")
|
|
175
|
+
annotationView?.image = self.createDefaultMarkerImage()
|
|
176
|
+
annotationView?.centerOffset = CGPoint(x: 0, y: -18)
|
|
142
177
|
}
|
|
143
178
|
} else {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
179
|
+
print("📍 [MarkerView] 没有子视图,使用默认图标")
|
|
180
|
+
annotationView?.image = self.createDefaultMarkerImage()
|
|
181
|
+
annotationView?.centerOffset = CGPoint(x: 0, y: -18)
|
|
147
182
|
}
|
|
183
|
+
|
|
184
|
+
return annotationView
|
|
148
185
|
}
|
|
149
186
|
|
|
150
187
|
/**
|
|
@@ -270,22 +307,75 @@ class MarkerView: ExpoView {
|
|
|
270
307
|
return UIGraphicsGetImageFromCurrentImageContext()
|
|
271
308
|
}
|
|
272
309
|
|
|
310
|
+
/**
|
|
311
|
+
* 当视图即将从父视图移除时调用
|
|
312
|
+
*/
|
|
313
|
+
override func willMove(toSuperview newSuperview: UIView?) {
|
|
314
|
+
super.willMove(toSuperview: newSuperview)
|
|
315
|
+
|
|
316
|
+
// 如果 newSuperview 为 nil,说明视图正在被移除
|
|
317
|
+
if newSuperview == nil {
|
|
318
|
+
removeAnnotationFromMap()
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* 从地图移除标记点
|
|
324
|
+
*/
|
|
325
|
+
private func removeAnnotationFromMap() {
|
|
326
|
+
guard !isRemoving else { return }
|
|
327
|
+
isRemoving = true
|
|
328
|
+
|
|
329
|
+
print("🗑️ [MarkerView] removeAnnotationFromMap 被调用")
|
|
330
|
+
|
|
331
|
+
// 取消任何待处理的延迟任务
|
|
332
|
+
pendingAddTask?.cancel()
|
|
333
|
+
pendingAddTask = nil
|
|
334
|
+
|
|
335
|
+
// 立即保存引用并清空属性,避免在异步块中访问 self
|
|
336
|
+
guard let mapView = mapView, let annotation = annotation else {
|
|
337
|
+
print("⚠️ [MarkerView] 没有 annotation 需要移除")
|
|
338
|
+
return
|
|
339
|
+
}
|
|
340
|
+
self.annotation = nil
|
|
341
|
+
self.annotationView = nil
|
|
342
|
+
|
|
343
|
+
// 同步移除,避免对象在异步块执行时已被释放
|
|
344
|
+
if Thread.isMainThread {
|
|
345
|
+
mapView.removeAnnotation(annotation)
|
|
346
|
+
print("✅ [MarkerView] Annotation 已从地图移除(主线程)")
|
|
347
|
+
} else {
|
|
348
|
+
DispatchQueue.main.sync {
|
|
349
|
+
mapView.removeAnnotation(annotation)
|
|
350
|
+
print("✅ [MarkerView] Annotation 已从地图移除(同步到主线程)")
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
273
355
|
override func willRemoveSubview(_ subview: UIView) {
|
|
274
356
|
super.willRemoveSubview(subview)
|
|
275
357
|
|
|
276
|
-
//
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
358
|
+
// 如果正在移除,不要执行任何操作
|
|
359
|
+
guard !isRemoving else {
|
|
360
|
+
print("⚠️ [MarkerView] willRemoveSubview 被调用但正在移除,忽略")
|
|
361
|
+
return
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
print("🎨 [MarkerView] willRemoveSubview 被调用,剩余 subviews.count: \(self.subviews.count - 1)")
|
|
365
|
+
|
|
366
|
+
// 子视图移除后,需要刷新 annotation 视图
|
|
367
|
+
if self.subviews.count <= 1 {
|
|
368
|
+
// 所有子视图已移除,刷新以恢复默认图标
|
|
369
|
+
if let mapView = mapView, let annotation = annotation {
|
|
370
|
+
DispatchQueue.main.async { [weak self] in
|
|
371
|
+
guard let self = self, !self.isRemoving else {
|
|
372
|
+
print("⚠️ [MarkerView] 异步刷新时已被移除,取消操作")
|
|
373
|
+
return
|
|
374
|
+
}
|
|
375
|
+
mapView.removeAnnotation(annotation)
|
|
376
|
+
mapView.addAnnotation(annotation)
|
|
377
|
+
print("✅ [MarkerView] Annotation 已刷新为默认图标")
|
|
285
378
|
}
|
|
286
|
-
} else {
|
|
287
|
-
// 还有子视图,更新图标
|
|
288
|
-
self.updateMarkerImage()
|
|
289
379
|
}
|
|
290
380
|
}
|
|
291
381
|
}
|
|
@@ -293,14 +383,26 @@ class MarkerView: ExpoView {
|
|
|
293
383
|
override func didAddSubview(_ subview: UIView) {
|
|
294
384
|
super.didAddSubview(subview)
|
|
295
385
|
|
|
296
|
-
//
|
|
297
|
-
|
|
298
|
-
|
|
386
|
+
// 如果正在移除,不要执行任何操作
|
|
387
|
+
guard !isRemoving else {
|
|
388
|
+
print("⚠️ [MarkerView] didAddSubview 被调用但正在移除,忽略")
|
|
389
|
+
return
|
|
299
390
|
}
|
|
300
391
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
392
|
+
print("🎨 [MarkerView] didAddSubview 被调用,subviews.count: \(self.subviews.count)")
|
|
393
|
+
|
|
394
|
+
// 子视图添加后,需要刷新 annotation 视图
|
|
395
|
+
// 通过移除并重新添加 annotation 来触发 getAnnotationView 调用
|
|
396
|
+
if let mapView = mapView, let annotation = annotation {
|
|
397
|
+
DispatchQueue.main.async { [weak self] in
|
|
398
|
+
guard let self = self, !self.isRemoving else {
|
|
399
|
+
print("⚠️ [MarkerView] 异步刷新时已被移除,取消操作")
|
|
400
|
+
return
|
|
401
|
+
}
|
|
402
|
+
mapView.removeAnnotation(annotation)
|
|
403
|
+
mapView.addAnnotation(annotation)
|
|
404
|
+
print("✅ [MarkerView] Annotation 已刷新")
|
|
405
|
+
}
|
|
304
406
|
}
|
|
305
407
|
}
|
|
306
408
|
|
|
@@ -415,11 +517,11 @@ class MarkerView: ExpoView {
|
|
|
415
517
|
}
|
|
416
518
|
|
|
417
519
|
/**
|
|
418
|
-
*
|
|
520
|
+
* 析构函数 - 不执行任何清理
|
|
521
|
+
* 清理工作已在 willMove(toSuperview:) 中完成
|
|
419
522
|
*/
|
|
420
523
|
deinit {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
}
|
|
524
|
+
// 不执行任何操作,避免访问已释放的对象
|
|
525
|
+
// 所有清理都应该在 willMove(toSuperview:) 中完成
|
|
424
526
|
}
|
|
425
527
|
}
|
|
@@ -45,29 +45,19 @@ class PolygonView: ExpoView {
|
|
|
45
45
|
* 更新多边形覆盖物
|
|
46
46
|
*/
|
|
47
47
|
private func updatePolygon() {
|
|
48
|
-
guard let mapView = mapView else {
|
|
49
|
-
print("❌ PolygonView.updatePolygon: mapView 为空")
|
|
50
|
-
return
|
|
51
|
-
}
|
|
48
|
+
guard let mapView = mapView else { return }
|
|
52
49
|
if let old = polygon { mapView.remove(old) }
|
|
53
50
|
|
|
54
51
|
var coords = points.compactMap { point -> CLLocationCoordinate2D? in
|
|
55
52
|
guard let lat = point["latitude"], let lng = point["longitude"] else { return nil }
|
|
56
53
|
return CLLocationCoordinate2D(latitude: lat, longitude: lng)
|
|
57
54
|
}
|
|
58
|
-
guard !coords.isEmpty else {
|
|
59
|
-
print("❌ PolygonView.updatePolygon: 点数组为空")
|
|
60
|
-
return
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
print("🔶 PolygonView.updatePolygon: points=\(coords.count)个点")
|
|
64
|
-
print("🔶 PolygonView.updatePolygon: fillColor=\(String(describing: fillColor)), strokeColor=\(String(describing: strokeColor)), strokeWidth=\(strokeWidth)")
|
|
55
|
+
guard !coords.isEmpty else { return }
|
|
65
56
|
|
|
66
57
|
polygon = MAPolygon(coordinates: &coords, count: UInt(coords.count))
|
|
67
58
|
mapView.add(polygon!)
|
|
68
59
|
|
|
69
60
|
renderer = nil
|
|
70
|
-
print("🔶 PolygonView.updatePolygon: renderer 已清空")
|
|
71
61
|
}
|
|
72
62
|
|
|
73
63
|
/**
|
|
@@ -48,29 +48,19 @@ class PolylineView: ExpoView {
|
|
|
48
48
|
* 更新折线覆盖物
|
|
49
49
|
*/
|
|
50
50
|
private func updatePolyline() {
|
|
51
|
-
guard let mapView = mapView else {
|
|
52
|
-
print("❌ PolylineView.updatePolyline: mapView 为空")
|
|
53
|
-
return
|
|
54
|
-
}
|
|
51
|
+
guard let mapView = mapView else { return }
|
|
55
52
|
if let old = polyline { mapView.remove(old) }
|
|
56
53
|
|
|
57
54
|
var coords = points.compactMap { point -> CLLocationCoordinate2D? in
|
|
58
55
|
guard let lat = point["latitude"], let lng = point["longitude"] else { return nil }
|
|
59
56
|
return CLLocationCoordinate2D(latitude: lat, longitude: lng)
|
|
60
57
|
}
|
|
61
|
-
guard !coords.isEmpty else {
|
|
62
|
-
print("❌ PolylineView.updatePolyline: 点数组为空")
|
|
63
|
-
return
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
print("🔷 PolylineView.updatePolyline: points=\(coords.count)个点")
|
|
67
|
-
print("🔷 PolylineView.updatePolyline: strokeColor=\(String(describing: strokeColor)), strokeWidth=\(strokeWidth), texture=\(String(describing: textureUrl))")
|
|
58
|
+
guard !coords.isEmpty else { return }
|
|
68
59
|
|
|
69
60
|
polyline = MAPolyline(coordinates: &coords, count: UInt(coords.count))
|
|
70
61
|
mapView.add(polyline!)
|
|
71
62
|
|
|
72
63
|
renderer = nil
|
|
73
|
-
print("🔷 PolylineView.updatePolyline: renderer 已清空")
|
|
74
64
|
}
|
|
75
65
|
|
|
76
66
|
/**
|
|
@@ -20,7 +20,6 @@ class PermissionManager: NSObject, CLLocationManagerDelegate {
|
|
|
20
20
|
* @param callback 权限结果回调 (granted, status)
|
|
21
21
|
*/
|
|
22
22
|
func requestPermission(callback: @escaping (Bool, String) -> Void) {
|
|
23
|
-
print("🔐 [PermissionManager] requestPermission 被调用")
|
|
24
23
|
self.permissionCallback = callback
|
|
25
24
|
|
|
26
25
|
// 确保在主线程操作
|