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

Google Maps iOS自定义InfoWindow(信息窗口)实现问题求助

实现Google Maps iOS自定义信息窗口(InfoWindow)

嘿,我来帮你搞定这个自定义InfoWindow的实现,结合你现有的文件结构,分步骤来操作就行:

第一步:完善CustomInfoWindow.swift的配置

首先得确保你的CustomInfoWindow类能正确加载XIB,并且关联好控件,还要给按钮点击留好回调入口:

import UIKit

class CustomInfoWindow: UIView {
    // 关联XIB里的两个标签和按钮
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var detailLabel: UILabel!
    @IBOutlet weak var actionButton: UIButton!
    
    // 快速从XIB创建实例的便捷方法
    class func loadFromNib() -> CustomInfoWindow {
        return UINib(nibName: "CustomInfoWindow", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! CustomInfoWindow
    }
    
    // 用闭包传递按钮点击事件(InfoWindow是快照,直接IBAction不会生效)
    var onButtonTap: (() -> Void)?
    
    @IBAction func buttonClicked(_ sender: UIButton) {
        onButtonTap?()
    }
}

第二步:在ViewController中实现地图代理方法

接下来在你的ViewController里,实现GMSMapViewDelegate的关键方法,把自定义窗口绑定到标记点上,还要处理数据填充和事件回调:

import UIKit
import GoogleMaps

class ViewController: UIViewController, GMSMapViewDelegate {
    // 你的现有属性
    var map: GMSMapView!
    var longitudes: [Double]!
    var latitudes: [Double]!
    var architectNames: [String]! // 假设你有对应的建筑师名称数组
    var markerDescriptions: [String]! // 标记点的详情描述数组
    
    // 记录当前选中的标记点索引,方便后续处理
    private var currentSelectedMarkerIndex: Int?

    override func viewDidLoad() {
        super.viewDidLoad()
        // 初始化地图(保留你原来的代码,这里补个示例)
        let initialCamera = GMSCameraPosition.camera(withLatitude: 39.9042, longitude: 116.4074, zoom: 10)
        map = GMSMapView.map(withFrame: view.bounds, camera: initialCamera)
        map.delegate = self
        view.addSubview(map)
        
        // 添加标记点(根据你的数据循环创建,这里给个示例)
        for index in 0..<latitudes.count {
            let coordinate = CLLocationCoordinate2D(latitude: latitudes[index], longitude: longitudes[index])
            let marker = GMSMarker(position: coordinate)
            // 给marker设置tag,方便后续获取对应的数据索引
            marker.tag = index
            marker.map = map
        }
    }
    
    // 这个方法返回自定义的InfoWindow
    func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
        guard let markerIndex = marker.tag as? Int else { return nil }
        
        // 加载自定义窗口
        let customWindow = CustomInfoWindow.loadFromNib()
        
        // 填充数据到窗口的标签里
        customWindow.titleLabel.text = architectNames[markerIndex]
        customWindow.detailLabel.text = markerDescriptions[markerIndex]
        
        // 设置按钮点击的回调逻辑
        customWindow.onButtonTap = { [weak self] in
            guard let self = self else { return }
            // 这里写你点击按钮后的操作,比如弹窗、跳转页面
            print("标记点\(markerIndex)的按钮被点击啦!")
            // 也可以用currentSelectedMarkerIndex做更多操作
        }
        
        // 记录当前选中的标记点索引
        currentSelectedMarkerIndex = markerIndex
        
        return customWindow
    }
    
    // 可选:如果你需要处理InfoWindow本身的点击事件,实现这个方法
    func mapView(_ mapView: GMSMapView, didTapInfoWindowOf marker: GMSMarker) {
        guard let index = marker.tag as? Int else { return }
        print("点击了标记点\(index)的信息窗口")
        // 这里添加窗口点击的业务逻辑
    }
}

第三步:XIB的关键设置

别忘了检查你的CustomInfoWindow.xib的设置:

  • 把根视图的Class设置为CustomInfoWindow(不要给File's Owner设置类)
  • 确保标签、按钮都正确关联到CustomInfoWindow.swift的IBOutlet上,按钮的点击事件关联到buttonClicked:方法
  • 可以给XIB里的控件设置自动布局约束,这样窗口会根据内容自动调整大小

小提示

Google Maps的InfoWindow实际上是生成的快照,所以直接在InfoWindow里的控件添加点击事件不会生效,我们用闭包把事件传递到ViewController处理是最靠谱的方式~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:26:23