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

Swift实现Google Maps仅刷新标记而非整个地图的方法

解决Google Maps仅刷新车辆标记而非整个地图的问题

你的核心问题是每次定时器触发时都重新创建了新的标记(Marker)和路线(Polyline),而非更新已有实例,导致地图上堆积大量元素,看起来像是整个地图在刷新。下面是具体的修改方案:

步骤1:将Marker和Polyline改为类成员变量

首先在类里声明全局的标记和路线对象,这样不需要每次都重新创建实例:

var driverLatitude: Double?
var driverLongitude: Double?
var pickupLatitude: Double? // 假设你已定义该变量
var pickupLongitude: Double? // 假设你已定义该变量

// 新增全局的标记和路线对象,仅初始化一次
var vehicleMarker: GMSMarker?
var routePolyline: GMSPolyline?

步骤2:初始化Marker样式(仅执行一次)

在viewDidLoad里完成车辆标记的样式初始化,后续只需要更新位置即可:

override func viewDidLoad() {
    self.tripLocDetailsTimer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(tripLocDetailCustomrWebserviceCall), userInfo: nil, repeats: true)
    
    // 初始化车辆标记的样式,仅执行一次
    let cabIM = UIImageView(frame: CGRect(x: 0, y: 0, width: 40, height: 15))
    cabIM.image = UIImage(named: "bike_color")
    vehicleMarker = GMSMarker()
    vehicleMarker?.iconView = cabIM
    vehicleMarker?.infoWindowAnchor = CGPoint(x: 0.44, y: 0.40)
    vehicleMarker?.tracksViewChanges = false
    vehicleMarker?.map = self.mapView
}

步骤3:修改showingThePath()方法,仅更新已有实例

现在只需要更新标记的位置,以及按需更新路线路径,不再重复创建新的Marker和Polyline:

func storingDataOftripLocDetails(_ data: TripLocationDetailsResponse){
    self.driverLatitude = data.locationDetails?.driverDetails?.pickupLatitude
    self.driverLongitude = data.locationDetails?.driverDetails?.pickupLongitude
    self.showingThePath()
}

func showingThePath(){
    // 用guard let避免强制解包导致崩溃
    guard let driverLat = driverLatitude, let driverLng = driverLongitude,
          let pickupLat = pickupLatitude, let pickupLng = pickupLongitude else {
        return
    }
    
    // 仅更新车辆标记的位置
    let vehicleLocation = CLLocationCoordinate2D(latitude: driverLat, longitude: driverLng)
    vehicleMarker?.position = vehicleLocation
    
    // 构建路线请求URL
    let origin = "\(driverLat),\(driverLng)"
    let destination = "\(pickupLat),\(pickupLng)"
    guard let url = URL(string: "https://maps.googleapis.com/maps/api/directions/json?origin=\(origin)&destination=\(destination)") else {
        return
    }
    
    URLSession.shared.dataTask(with: url, completionHandler: {(data, response, error) in
        if let error = error {
            print("获取路线失败:\(error.localizedDescription)")
            return
        }
        
        guard let data = data else {
            print("无路线数据返回")
            return
        }
        
        do{
            let json = try JSONSerialization.jsonObject(with: data, options:.allowFragments) as! [String : Any]
            print(json)
            
            guard let status = json["status"] as? String, status == "OK" else {
                print("路线请求状态异常")
                return
            }
            
            guard let routes = json["routes"] as? [[String:Any]], let firstRoute = routes.first else {
                print("无可用路线")
                return
            }
            
            OperationQueue.main.addOperation({
                guard let routeOverviewPolyline = firstRoute["overview_polyline"] as? [String:String],
                      let points = routeOverviewPolyline["points"],
                      let path = GMSPath.init(fromEncodedPath: points) else {
                    return
                }
                
                // 如果已有路线实例,仅更新路径;否则创建新的路线
                if let polyline = self.routePolyline {
                    polyline.path = path
                } else {
                    self.routePolyline = GMSPolyline(path: path)
                    self.routePolyline?.strokeColor = .gray
                    self.routePolyline?.strokeWidth = 3.0
                    self.routePolyline?.map = self.mapView
                }
            })
        }catch let error as NSError{
            print("解析路线数据失败:\(error.localizedDescription)")
        }
    }).resume()
}

额外优化建议

  • 减少API调用:如果终点(pickup位置)固定,可以不用每次定时器触发都请求路线,只在司机位置变化时更新标记即可
  • 定时器生命周期管理:在viewWillDisappear中调用tripLocDetailsTimer?.invalidate(),避免内存泄漏
  • 错误处理增强:可以给用户添加友好的错误提示,比如路线请求失败时显示Toast

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:27:32