【问题标题】:Custom marker infowindow using google maps ios sdk and swiftui使用谷歌地图 ios sdk 和 swiftui 自定义标记信息窗口
【发布时间】:2020-03-05 16:25:37
【问题描述】:

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

我一直在这里参考 Google 的文档:https://developers.google.com/maps/documentation/ios-sdk/reference/protocol_g_m_s_map_view_delegate-p

目前,我可以通过返回 UIView 在 GMSMapViewDelegate 上使用“markerInfoWindow”方法显示自定义信息窗口,但由于我的几乎所有应用程序都是使用 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 还很陌生,所以这对于更有经验的开发人员来说可能很明显,但是有什么方法可以将我的 swiftui 视图返回为 UIView,以便我可以在信息窗口中显示它?

或者,如果这是我唯一的选择,是否有办法轻松设置 UIView 的样式,以便它可以混合使用 HStack 和 VStack?

【问题讨论】:

    标签: swift google-maps uiview google-maps-markers swiftui


    【解决方案1】:

    我认为您可以在这种情况下使用UIHostingController。我没有在谷歌地图中尝试过这个,因为我没有使用它们的项目所以 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)
    }
    

    【讨论】:

    • 感谢您的帮助!为简单起见,我认为我将更改视图以使其具有信息性并且不包含按钮。但是我复制了您上面的代码并不断收到错误“无法将'UIView'类型的值分配给'CGRect'类型”。我尝试将标注的视图和 view.frame 设置为 UIView() 但没有运气。你有什么想法吗?
    • 抱歉,这是我的错,从我的 MapKit 设置转置到您的 GoogleMap 时出现复制和粘贴错误。它应该只是包含在UIView 中的CGRect。我已经更新了代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-03
    • 2017-07-13
    • 2013-08-19
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    相关资源
    最近更新 更多