소스 검색

fix annotation reuse issue

Groot 6 달 전
부모
커밋
3bc490788f

+ 4 - 3
plugins/map_mapkit_ios/ios/Classes/MapView/MapViewController.swift

@@ -62,7 +62,9 @@ class MapViewController: UIViewController {
             .receive(on: DispatchQueue.main)
             .sink { [weak self] markers in
                 self?.mapView.removeAnnotations(self?.mapView.annotations ?? [])
-                self?.mapView.addAnnotations(markers)
+                UIView.animate(withDuration: 0.3) {
+                    self?.mapView.addAnnotations(markers)
+                }
             }
             .store(in: &cancellables)
 
@@ -90,10 +92,9 @@ extension MapViewController: MKMapViewDelegate {
             return nil
         }
         
-        let annotationView = (mapView.dequeueReusableAnnotationView(withIdentifier: marker.markerType.imageName(selected: marker.isSelected)) as? MapAnnotationView) ?? MapAnnotationView(annotation: marker, reuseIdentifier: marker.markerType.imageName(selected: marker.isSelected))
+        let annotationView = (mapView.dequeueReusableAnnotationView(withIdentifier: MapAnnotationView.identifier) as? MapAnnotationView) ?? MapAnnotationView(annotation: marker, reuseIdentifier: MapAnnotationView.identifier)
         annotationView.marker = marker
         annotationView.prepareForDisplay()
-        annotationView.prepareForReuse()
         return annotationView
     }
 

+ 6 - 5
plugins/map_mapkit_ios/ios/Classes/MapView/ViewModel/MapViewModel.swift

@@ -44,18 +44,19 @@ class MapViewModel: NSObject, ObservableObject, MapCapability {
 
     // 处理地图添加Marker
     func handleMapAddMarker(args: [[String: Any]]?, result: @escaping FlutterResult) {
-        guard let args = args, let markers = [ATMapMarker].fromJson(json: args) else {
+        guard let args = args, let newMarkers = [ATMapMarker].fromJson(json: args) else {
             result(paramsDecodeError)
             return
         }
-        // 使用字典优化查找性能
+        
         var markerDict = Dictionary(uniqueKeysWithValues: self.markers.map { ($0.id, $0) })
         
-        markerDict.merge(Dictionary(uniqueKeysWithValues: markers.map { ($0.id, $0) }), uniquingKeysWith: { _, new in new })
+        for marker in newMarkers {
+            markerDict[marker.id] = marker
+        }
         
-        // 转换回数组
         self.markers = Array(markerDict.values)
-        print("Add Marker: -- \(markers)")
+        print("Update Markers: --- \(markerDict["user_location"]?.markerType)")
         result(nil)
     }
 

+ 17 - 3
plugins/map_mapkit_ios/ios/Classes/MapView/Views/MapAnnotationMarkerImageView.swift

@@ -11,7 +11,9 @@ class MapAnnotationMarkerImageView: UIView {
     let markerType: any MapMarkerSupportType
     var isSelected: Bool = false {
         didSet {
-            imageView.image = uiImage
+            if oldValue != isSelected {
+                updateImage()
+            }
         }
     }
 
@@ -28,10 +30,22 @@ class MapAnnotationMarkerImageView: UIView {
     }
 
     private func setupImageView() {
-        imageView.image = uiImage
         imageView.contentMode = .scaleAspectFit
-        imageView.frame = CGRect(origin: .init(), size: markerType.size)
+        imageView.translatesAutoresizingMaskIntoConstraints = false
         addSubview(imageView)
+        
+        NSLayoutConstraint.activate([
+            imageView.topAnchor.constraint(equalTo: topAnchor),
+            imageView.bottomAnchor.constraint(equalTo: bottomAnchor),
+            imageView.leadingAnchor.constraint(equalTo: leadingAnchor),
+            imageView.trailingAnchor.constraint(equalTo: trailingAnchor)
+        ])
+        
+        updateImage()
+    }
+    
+    private func updateImage() {
+        imageView.image = uiImage
     }
 
     private var uiImage: UIImage? {

+ 41 - 17
plugins/map_mapkit_ios/ios/Classes/MapView/Views/MapAnnotationView.swift

@@ -12,8 +12,12 @@ class MapAnnotationView: MKAnnotationView {
     
     static let identifier: String = "MapAnnotationView"
 
-    var marker: ATMapMarker?
-    var markerImageView: MapAnnotationMarkerImageView!
+    var marker: ATMapMarker? {
+        didSet {
+            updateView()
+        }
+    }
+    var markerImageView: MapAnnotationMarkerImageView?
     var textView: MapAnnotationMarkerTextView?
     
     // spacing between text and image
@@ -24,28 +28,45 @@ class MapAnnotationView: MKAnnotationView {
     }
     
     override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
-        self.marker = annotation as? ATMapMarker
         super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
-        
+        self.marker = annotation as? ATMapMarker
         self.isEnabled = marker?.markerType.supportSelected ?? false
         self.isHidden = false
-        setupViews()
     }
 
     required init?(coder aDecoder: NSCoder) {
         fatalError("init(coder:) has not been implemented")
     }
     
-    // MARK: - 设置视图
+    // MARK: - 视图更新与重用
+    
+    override func prepareForReuse() {
+        super.prepareForReuse()
+        // 清除当前所有子视图
+        for subview in subviews {
+            subview.removeFromSuperview()
+        }
+        markerImageView = nil
+        textView = nil
+    }
     
-    private func setupViews() {
+    private func updateView() {
+        // 确保在更新视图前移除所有子视图
+        for subview in subviews {
+            subview.removeFromSuperview()
+        }
+        
+        guard let marker = marker else { return }
+        
         // 创建并添加图像视图
-        markerImageView = MapAnnotationMarkerImageView(markerType: marker?.markerType ?? MarkerType.mine)
-        markerImageView.isSelected = annotationSelected
-        addSubview(markerImageView)
+        markerImageView = MapAnnotationMarkerImageView(markerType: marker.markerType)
+        if let markerImageView = markerImageView {
+            markerImageView.isSelected = annotationSelected
+            addSubview(markerImageView)
+        }
         
         // 如果有标题,添加文本视图
-        if let markerName = marker?.markerName, !markerName.isEmpty {
+        if let markerName = marker.markerName, !markerName.isEmpty {
             textView = MapAnnotationMarkerTextView(text: markerName)
             if let textView = textView {
                 addSubview(textView)
@@ -61,6 +82,8 @@ class MapAnnotationView: MKAnnotationView {
     private func setupConstraints() {
         // 禁用自动约束转换
         translatesAutoresizingMaskIntoConstraints = false
+        
+        guard let markerImageView = markerImageView else { return }
         markerImageView.translatesAutoresizingMaskIntoConstraints = false
         
         let markerSize = marker?.markerType.size ?? CGSize(width: 30, height: 30)
@@ -122,16 +145,17 @@ class MapAnnotationView: MKAnnotationView {
     
     override func prepareForDisplay() {
         super.prepareForDisplay()
-        updateImage()
-    }
-    
-    private func updateImage() {
-        markerImageView.isSelected = annotationSelected
+        // 确保视图已经设置好
+        if markerImageView == nil {
+            updateView()
+        }
+        // 更新选中状态
+        markerImageView?.isSelected = annotationSelected
     }
 
     override func setSelected(_ selected: Bool, animated: Bool) {
         super.setSelected(selected, animated: animated)
         marker?.isSelected = selected
-        updateImage()
+        markerImageView?.isSelected = annotationSelected
     }
 }