You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS开发如何在MKMapView地图上展示自定义图片类型的标注视图

iOS地图自定义图片标注实现方案

现有代码问题

你的代码存在两个核心错误导致自定义标注无法生效:

  1. 没有给MKMapView设置代理,也没有实现标注视图的代理回调方法,你在viewDidLoad中创建的MKAnnotationView没有和地图标注绑定,完全不会生效
  2. viewDidLoad中只需要添加标注数据(MKPointAnnotation),标注视图的创建和配置需要在专属代理方法中完成

调整步骤

1. 改造viewDidLoad逻辑

删除循环内创建MKAnnotationView的无用代码,添加地图代理设置

2. 实现MKMapViewDelegate代理方法

实现mapView(_:viewFor:)方法,在方法内完成自定义标注视图的配置、复用逻辑

3. 可选优化

设置centerOffset调整图片显示位置,避免图片中心直接覆盖坐标点;开启canShowCallout支持点击弹出气泡

完整可运行代码

import UIKit
import MapKit

class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
    @IBOutlet weak var mapView: MKMapView!
    let loc = [["Title": "Banglore",
                "Latitude": 12.9716,
                "longtitute": 77.5946,
                "SubTitle": "karnataka",
                "Detial": "This is our capital"],
               ["Title": "Mumbai",
                "Latitude": 19.0760,
                "longtitute": 72.8777,
                "SubTitle": "Mahrasthra",
                "Detial": "This is our capital"],
               ["Title": "Shimla",
                "Latitude": 31.1048,
                "longtitute": 77.1734,
                "SubTitle": "Himachal",
                "Detial": "This is our capital"]]

    override func viewDidLoad() {
        super.viewDidLoad()
        // 设置地图代理
        mapView.delegate = self
        // 仅添加标注数据,不处理视图
        for location in loc {                
            let annotaion = MKPointAnnotation()
            annotaion.title = location["Title"] as? String
            annotaion.subtitle = location["SubTitle"] as? String
            let locations = CLLocationCoordinate2D(latitude: location["Latitude"] as! Double, longitude: location["longtitute"] as! Double)
            annotaion.coordinate = locations
            mapView.addAnnotation(annotaion)
        }  
    }
    
    // MARK: - MKMapViewDelegate
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        // 排除用户位置的蓝色圆点标注
        guard !(annotation is MKUserLocation) else { return nil }
        // 标注视图复用标识
        let reuseId = "CustomAnnotation"
        // 先从复用池取视图
        var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
        if annotationView == nil {
            // 复用池为空则创建新视图
            annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
            // 设置自定义图片
            annotationView?.image = UIImage(named: "rose")
            // 调整图片偏移,让图片底部对准坐标点,可根据你的图片尺寸调整数值
            annotationView?.centerOffset = CGPoint(x: 0, y: -(annotationView?.image?.size.height ?? 0)/2)
            // 开启点击弹出气泡功能,不需要可以删掉
            annotationView?.canShowCallout = true
        } else {
            // 复用视图时更新绑定的标注数据
            annotationView?.annotation = annotation
        }
        return annotationView
    }
}

注意事项

  • 确保名为rose的图片已经正确添加到Xcode项目中,文件名拼写完全一致
  • 如果需要自定义气泡的内容,可以在上述代理方法中给annotationView的leftCalloutAccessoryView、rightCalloutAccessoryView设置自定义视图

内容的提问来源于stack exchange,提问作者Deepaman Bawa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 08:42:01