我想要完成的是每 X 秒刷新一次地图。这样做时,我想更新所选标记的信息窗口的内容。但是,标记数据已更新(尝试使用纬度/经度),但信息窗口数据保持不变。如何更新信息窗口数据,而无需重新创建它?
如果我总是重新创建信息窗口(重新选择标记),信息窗口内容会发生变化,但用户体验很糟糕,因为信息窗口正在闪烁。
更新标记数据的代码
private func updateMarker(index: Int, markerData: MarkerData, select: Bool) {
markersOnMap[index].title = markerData.time.description
if markersOnMap[index].hasChangedPosition(markerData: markerData) {
markersOnMap[index].position = markerData.getPosition()
UIImpactFeedbackGenerator(style: .heavy).impactOccurred()
}
//Info window is recreated, but the UI is awful
//if select {
//mapView?.selectedMarker = nil
//mapView?.selectedMarker = markersOnMap[index]
//}
}
创建标记并将其添加到地图的代码:
private func addMarker(markerData: MarkerData, select: Bool) {
let marker = GMSMarker()
marker.map = mapView
marker.position = markerData.getPosition()
marker.userData = markerData.tranId
marker.title = markerData.time.description
marker.groundAnchor = CGPoint(x: 0.5, y: 0.5)
if select == true {
//Where markerInfoWindow is created
marker.icon = UIImage(named: MyImages.markerIcon)
marker.tracksInfoWindowChanges = true
mapView?.selectedMarker = marker
} else {
marker.iconView = getMyIconView(posTime: markerData.time)
}
markersOnMap.append(marker)
}
信息窗口创建
func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
let posTime = CLong(marker.title ?? "0") ?? 0
var rect = CGRect(x: 0, y: 0, width: 150, height: 140)
let hostingController = UIHostingController(rootView: MyInfoView(device: device, posTime: posTime))
hostingController.view.frame = rect
hostingController.view.backgroundColor = .clear
return hostingController.view
}
由于无法通过标记更新来实现所需的行为,因此我妥协于 hostingController。我将其转换为局部变量,该变量在创建标记信息窗口后进行初始化。 每次我想要更新信息窗口数据时,我都会使用托管控制器的实例来执行此操作。
初始化托管控制器
func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
let posTime = CLong(marker.title ?? "0") ?? 0
hostingController = UIHostingController(rootView: MyInfoView(device: device, posTime: posTime))
hostingController?.view.frame = CGRect(x: 0, y: 0, width: 150, height: 140)
hostingController?.view.backgroundColor = .clear
return hostingController?.view
}
更新信息窗口数据(本例中为 posTime)
private func updateMarker(index: Int, markerData: MarkerData, select: Bool) {
markersOnMap[index].title = markerData.time.description
if markersOnMap[index].hasChangedPosition(markerData: markerData) {
markersOnMap[index].position = markerData.getPosition()
UIImpactFeedbackGenerator(style: .heavy).impactOccurred()
}
if select {
hostingController?.rootView.posTime = markerData.time
}
}