使用 google 地图 ios sdk 和 swiftui 的自定义标记信息窗口

Custom marker infowindow using google maps ios sdk and swiftui

在我的应用程序中,我试图在使用 GoogleMaps 和 SwiftUI 视图点击标记 (GMSMarker) 时显示自定义信息窗口。

我在这里引用了 Google 的文档:https://developers.google.com/maps/documentation/ios-sdk/reference/protocol_g_m_s_map_view_delegate-p

目前,我可以通过 returning UIView 在我的 GMSMapViewDelegate 上使用 'markerInfoWindow' 方法显示自定义信息窗口,但由于我几乎所有的应用程序都是 built使用 swiftui 视图我希望能够显示现有的 swiftui 视图,而不是将视图重新创建为 UIView。

这是我当前的函数,它创建然后显示一个基本的 UIView 作为信息窗口(它是一个带有文本的灰色框):

    func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView {
        print("Showing marker infowindow")
        let mInfoWindow = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width - 48, height: 200))
        mInfoWindow.backgroundColor = UIColor.lightGray
        mInfoWindow.layer.cornerRadius = 6

        let lbl1 = UILabel(frame: CGRect.init(x: 8, y: 8, width: view.frame.size.width - 16, height: 15))
        lbl1.text = "Hi there!"
        mInfoWindow.addSubview(lbl1)


        return mInfoWindow
    }

这是我希望能够显示的 swiftui 视图:

import SwiftUI
import UIKit

struct MarkerInfoWindow: View {
    var body: some View {

        HStack {
            Text("Image here")

            VStack {
                Text("Content 1")
                Text("Content 2")

            }

            Text("button here")
        }

    }
}

我是 swift 的新手,所以这对更有经验的开发人员来说可能很明显,但是有什么方法可以 return 我的 swiftui 作为 UIView 查看以便我可以在信息窗口中显示它?

或者有没有一种方法可以轻松设置我的 UIView 的样式,如果那是我唯一的选择,它可以是 HStack 和 VStack 的混合体?

我认为您可以在这种情况下使用 UIHostingController。我没有在 Google 地图中尝试过这个,因为我没有使用它们的项目,所以 YMMV,但它至少可以给你一个起点。

要使用UIHostingController我们可以传递我们想要使用的SwiftUI视图。您可以在 SwiftUI 中设置它的大小,也可以在标注中添加一个框架。

func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView {
    print("Showing marker infowindow") 
    let callout = UIHostingController(rootView: MarkerInfoWindow())
    callout.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width - 48, height: 200)
    return callout.view
}

您的 MarkerInfoWindow 看起来您打算在其中添加一个按钮,我不确定您将如何实现它,这可能是在 SwiftUI 中添加一个按钮的简单情况代码,尽管我从过去的经验中知道,如果按钮不在标注配件之一内,则很难与标注进行交互。


这就是我在 MapKit 中用来显示标注的方法

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
    let callout = UIHostingController(rootView: MarkerInfoWindow())
    callout.view.frame = CGRect(x: 0, y: 0, width: mapView.frame.width - 48, height: 200)
    view.addSubview(callout.view)
}