In my app I am trying to make a custom infowindow appear when a marker (GMSMarker) is tapped using GoogleMaps and a SwiftUI view.
Ive been referencing Google's documentation here: https://developers.google.com/maps/documentation/ios-sdk/reference/protocol_g_m_s_map_view_delegate-p
At the moment I can display a custom infowindow using the 'markerInfoWindow' method on my GMSMapViewDelegate by returning a UIView, but since almost all of my app is built using swiftui views I would like to be able to display an existing swiftui view rather than recreate the view as a UIView.
Here is my current function that creates then displays a basic UIView as the infowindow (its a grey box with text on it):
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
}
Here is the swiftui view I would like to be able to show instead:
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")
}
}
}
Im fairly new to swift so this may be obvious to more experienced developers, but is there any way that I can return my swiftui view as a UIView so that I can display it in the infowindow?
Or is there a way to easily style my UIView so it can be a mixture of HStacks and VStacks if thats my only option?
I think that you could use UIHostingController
in this situation. I haven't tried this in Google maps as I don't have a project that uses them so YMMV, but it could at least give you a starting point.
To use UIHostingController
we can pass the SwiftUI
view that we want to use. You can style the size of it inside your SwiftUI
or you can add a frame to the callout.
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
}
Your MarkerInfoWindow
looks like you are planning to have a button in it, I am not sure how you would implement that, it may be a simple case of adding a button in the SwiftUI
code, though I know from past experience that it is difficult to interact with a callout if the button isn't inside one of the callout accessories.
This is what I did in MapKit
to show the callout
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)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.