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

Swift5中如何加载服务器图标设置为Google Maps的GMSMarker.icon

GMSMarker 加载网络图片设置icon方案

核心思路

你现有扩展是绑定UIImageView组件实现的,而GMSMarker.icon是UIImage?类型,不需要依赖图片视图实例,只需要把网络拉取到的图片数据转成UIImage实例,在主线程赋值给marker即可。

具体实现

1. 抽离通用图片加载逻辑(可选,推荐)

把原本耦合在UIImageView扩展里的图片请求逻辑抽成独立方法,方便不同场景复用,避免重复代码:

func loadImage(from urlString: String, completion: @escaping (UIImage?) -> Void) {
    // URL校验,不合法直接返回本地占位图
    guard let url = URL(string: urlString) else {
        completion(UIImage(named: "imp.png"))
        return
    }

    // 这里可以直接复用你原本封装的 self.load.request 相关缓存、请求逻辑
    // 以下是基础请求示例
    URLSession.shared.dataTask(with: url) { data, _, error in
        let resultImage: UIImage?
        defer {
            // UI赋值必须回到主线程
            DispatchQueue.main.async {
                completion(resultImage ?? UIImage(named: "imp.png"))
            }
        }
        guard error == nil, let data = data, let downloadedImg = UIImage(data: data) else {
            resultImage = nil
            return
        }
        resultImage = downloadedImg
    }.resume()
}

2. 给marker赋值图标

先配置marker的基础位置属性,再调用加载方法拿到图片后赋值:

// 配置marker基础信息
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(
    latitude: mapModel.yCoordinate,
    longitude: mapModel.xCoordinate
)
marker.map = yourMapView

// 加载并设置图标
loadImage(from: mapModel.iconUrl) { [weak marker] iconImg in
    marker?.icon = iconImg
}

3. 扩展GMSMarker简化调用(可选)

如果想和你现有UIImageView的调用风格保持一致,可以直接给GMSMarker写同名扩展:

extension GMSMarker {
    func load(str: String) {
        let url = URL(string: str)
        guard let validUrl = url else {
            self.icon = UIImage(named: "imp.png")
            return
        }
        
        // 复用你已有的图片请求逻辑即可,核心是拿到UIImage后赋值
        // 示例请求逻辑
        URLSession.shared.dataTask(with: validUrl) { [weak self] data, _, error in
            guard let self = self else { return }
            let setIconBlock = { (img: UIImage?) in
                DispatchQueue.main.async {
                    self.icon = img ?? UIImage(named: "imp.png")
                }
            }
            guard error == nil, let data = data, let img = UIImage(data: data) else {
                setIconBlock(nil)
                return
            }
            setIconBlock(img)
        }.resume()
    }
}

写完扩展后调用方式非常简洁:

marker.position = CLLocationCoordinate2D(latitude: mapModel.yCoordinate, longitude: mapModel.xCoordinate)
marker.load(str: mapModel.iconUrl)
marker.map = yourMapView

注意点:

  • 所有对GMSMarker的属性修改(包括设置icon)必须在主线程执行,否则会出现图标不刷新、显示异常的问题
  • 如果你的地图会展示大量marker,建议给图片加载增加内存/磁盘缓存,避免重复下载相同图标浪费流量、降低滑动性能

内容的提问来源于stack exchange,提问作者Mariam Sargsyan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:09:33