В настоящее время я создаю приложение с использованием SwiftUI и Google Maps. Я пытаюсь отобразить лист формы после нажатия на информационное окно маркера Google Maps, но у меня возникают проблемы с его работой.
В других частях своего приложения я отображаю листы, используя этот метод: Пример метода здесь
Я попытался использовать тот же метод, описанный выше, для отображения листа после нажатия на информационное окно маркера, но у меня возникли проблемы с выполнением этого из функции. Мои фрагменты кода ниже содержат более подробную информацию.
-
Ниже представлена урезанная версия моего файла GMView.swift, который управляет моим экземпляром Google Maps. (Мой файл отличается от типичной интеграции карт Swift + Google, потому что я использую SwiftUI). Вы заметите три основные части файла: 1. представление, 2. класс GMController и 3. структуру GMControllerRepresentable:
import SwiftUI
import UIKit
import GoogleMaps
import GooglePlaces
import CoreLocation
import Foundation
struct GoogMapView: View {
var body: some View {
GoogMapControllerRepresentable()
}
}
class GoogMapController: UIViewController, CLLocationManagerDelegate, GMSMapViewDelegate {
var locationManager = CLLocationManager()
var mapView: GMSMapView!
let defaultLocation = CLLocation(latitude: 42.361145, longitude: -71.057083)
var zoomLevel: Float = 15.0
let marker : GMSMarker = GMSMarker()
override func viewDidLoad() {
super.viewDidLoad()
// Control location data
locationManager.requestAlwaysAuthorization()
locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.distanceFilter = 50
locationManager.startUpdatingLocation()
}
let camera = GMSCameraPosition.camera(withLatitude: defaultLocation.coordinate.latitude, longitude: defaultLocation.coordinate.longitude, zoom: zoomLevel)
mapView = GMSMapView.map(withFrame: view.bounds, camera: camera)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.isMyLocationEnabled = true
mapView.setMinZoom(14, maxZoom: 20)
mapView.settings.compassButton = true
mapView.isMyLocationEnabled = true
mapView.settings.myLocationButton = true
mapView.settings.scrollGestures = true
mapView.settings.zoomGestures = true
mapView.settings.rotateGestures = true
mapView.settings.tiltGestures = true
mapView.isIndoorEnabled = false
marker.position = CLLocationCoordinate2D(latitude: 42.361145, longitude: -71.057083)
marker.title = "Boston"
marker.snippet = "USA"
marker.map = mapView
// view.addSubview(mapView)
mapView.delegate = self
self.view = mapView
}
// Handle incoming location events.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location: CLLocation = locations.last!
print("Location: \(location)")
}
// Handle authorization for the location manager.
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .restricted:
print("Location access was restricted.")
case .denied:
print("User denied access to location.")
// Display the map using the default location.
mapView.isHidden = false
case .notDetermined:
print("Location status not determined.")
case .authorizedAlways: fallthrough
case .authorizedWhenInUse:
print("Location status is OK.")
}
}
// Handle location manager errors.
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
locationManager.stopUpdatingLocation()
print("Error: \(error)")
}
}
struct GoogMapControllerRepresentable: UIViewControllerRepresentable {
func makeUIViewController(context: UIViewControllerRepresentableContext<GMControllerRepresentable>) -> GMController {
return GMController()
}
func updateUIViewController(_ uiViewController: GMController, context: UIViewControllerRepresentableContext<GMControllerRepresentable>) {
}
}
Это функция, которую я добавил в класс GMController в моем вышеупомянутом файле GMView.swift, который в документации Google сказано использовать для обработки при касании информационного окна маркера:
// Function to handle when a marker's infowindow is tapped
func mapView(_ mapView: GMSMapView, didTapInfoWindowOf didTapInfoWindowOfMarker: GMSMarker) {
print("You tapped a marker's infowindow!")
// This is where i need to get the view to appear as a modal, and my attempt below
let venueD2 = UIHostingController(rootView: VenueDetail2())
venueD2.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height - 48)
self.view.addSubview(venueD2.view)
return
}
Моя функция выше в настоящее время отображает представление при нажатии на информационное окно, но оно просто появляется поверх моего представления карт Google, поэтому я не получаю анимацию и не могу отклонить представление, как типичный лист формы iOS.
Кто-нибудь знает, как я могу отобразить лист после касания информационного окна маркера карт Google в SwiftUI вместо того, чтобы просто добавить его в качестве подпредставления?