繁体   English   中英

谷歌地图 iOS SDK 到用户在启动时的当前位置 Swift Z5D807DF8E2D0F6FCC3B5037BZ8AB9

[英]Google Maps iOS SDK to user's current location on launch Swift SwiftUI

我试图模仿谷歌地图的一些功能,在启动应用程序时,如果已授予所需的权限,相机就会移动到用户的当前位置。

我已经使用自定义当前位置按钮实现了这一点,该按钮可以很好地将相机带到用户当前位置,但在启动时无法模仿。 map 在位置管理器之后初始化,但是调用 didUpdateLocations 时会有延迟。 这意味着它发生在 map 完成初始化之后,因此 initialiseMapCamera() 默认坐标为 0,0。 如果没有正确的烫发,map 相机默认为 1,1,正如预期的那样。

我确信有一种明显的方法可以解决我没有想到的问题; 非常感谢任何帮助。 谢谢!

LocationManager - 首先实例化

class LocationManager: NSObject, ObservableObject {
  
  private let locationManager = CLLocationManager()
  
  @Published var authorizationStatus: CLAuthorizationStatus = .notDetermined {
    willSet { objectWillChange.send() }
  }
  
  @Published var location: CLLocation? {
    willSet { objectWillChange.send() }
  }
  
  var latitude: CLLocationDegrees {
    return location?.coordinate.latitude ?? 0
  }
  
  var longitude: CLLocationDegrees {
    return location?.coordinate.longitude ?? 0
  }
  
  override init() {
    super.init()
    
    locationManager.delegate = self
    
    switch authorizationStatus {
    case .authorizedAlways, .authorizedWhenInUse:
      configureLocationSettings()
    case .notDetermined, .restricted, .denied: break
    @unknown default: fatalError()
    }
  }
  
  func configureLocationSettings() {
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.startUpdatingLocation()
  }
  
  func requestLocationPermissions() {
    locationManager.requestWhenInUseAuthorization()
  }
}

extension LocationManager: CLLocationManagerDelegate {

  func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let location = locations.last else { return }
    self.location = location
  }
  
  func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
    self.authorizationStatus = manager.authorizationStatus

    switch authorizationStatus {
    case .authorizedAlways, .authorizedWhenInUse:
      configureLocationSettings()
    case .notDetermined, .restricted, .denied: return
    @unknown default: 
      fatalError()
    }
  }
}

MapViewBridge - 之后实例化

struct MapViewControllerBridge: UIViewControllerRepresentable {
  
  @EnvironmentObject var locationManager: LocationManager
  @EnvironmentObject var mapViewModel: mapViewModel

  func makeUIViewController(context: Context) -> MapViewController {
    let uiViewController = MapViewController()
    initialiseMapCamera(mapView: uiViewController.mapView)
    return uiViewController
  }

  func updateUIViewController(_ uiViewController: MapViewController, context: Context) { 
    cameraToLocationButton(mapView: uiViewController.mapView)
  }
  
  private func initialiseMapCamera(mapView: GMSMapView) {
    var cameraLocation: CLLocationCoordinate2D
    
    switch locationManager.authorizationStatus {
    case .authorizedAlways, .authorizedWhenInUse:
      cameraLocation = CLLocationCoordinate2D(
        latitude: locationManager.latitude,
        longitude: locationManager.longitude)
    case .notDetermined, .restricted, .denied:
      cameraLocation = CLLocationCoordinate2D(latitude: 1.0, longitude: 1.0)
    @unknown default:
      fatalError()
    }
    mapView.camera = GMSCameraPosition.camera(withTarget: cameraLocation, zoom: defaultZoomLevel)
  }
  
  private func animateCameraToCurrentLocation(mapView: GMSMapView) {
    let currentLocation = CLLocationCoordinate2D(
      latitude: locationManager.latitude,
      longitude: locationManager.longitude)
    mapView.animate(with: GMSCameraUpdate.setTarget(currentLocation))
    mapView.animate(toZoom: defaultZoomLevel)
  }
  
  private func cameraToLocationButton(mapView: GMSMapView) {
    guard mapViewModel.cameraToLocation else {
      return
    }

    switch locationManager.authorizationStatus {
    case .authorizedWhenInUse, .authorizedAlways:
      animateCameraToCurrentLocation(mapView: mapView)
    case .notDetermined:
      locationManager.requestLocationPermissions()
    case .restricted, .denied:
      DispatchQueue.main.async {
        mapViewModel.showLocationSettingsAlert = true
      }
    @unknown default:
      fatalError()
    }
    
    DispatchQueue.main.async {
      mapViewModel.cameraToLocation = false
    }
  }
}

创建加载视图,直到位置更新。 然后一旦更新禁用加载视图并显示 map,它将在 map 视图出现时开始相机移动。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM