使用 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)
}
在我的应用程序中,我试图在使用 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)
}