在我的应用程序中,当使用GoogleMaps和SwiftUI视图点击标记(GMSMarker(时,我试图显示一个自定义信息窗口。
我一直在这里参考谷歌的文档:https://developers.google.com/maps/documentation/ios-sdk/reference/protocol_g_m_s_map_view_delegate-p
目前,我可以通过返回UIView,在GMSMapViewDelegate上使用"markInfoWindow"方法显示自定义信息窗口,但由于我的几乎所有应用程序都是使用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的混合
我认为在这种情况下可以使用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)
}