gpt4 book ai didi

swift - 如何使用 swiftUI View 在启动时将 Google map 相机聚焦在用户当前位置

转载 作者:行者123 更新时间:2023-11-30 10:34:39 38 4
gpt4 key购买 nike

我正在尝试制作一个使用 Google map 的应用,并在打开应用时重点关注用户的位置。

现在我已经初始化了 map ,按下 GoogleMaps 固有的“myLocation”按钮后,我能够聚焦于用户位置,但 map 的相机始终聚焦于指定位置,而不是用户位置。

我使用了这两个教程来达到我现在的水平:-https://developers.google.com/maps/documentation/ios-sdk/start-https://www.raywenderlich.com/197-google-maps-ios-sdk-tutorial-getting-started

搜索 Google 和此处后,似乎我需要利用 CLLocationManager() 来获取用户的设备坐标,然后以某种方式使用它?我认为我关于 CLLocationManager() 的代码可能放置在错误的文件中或使用不正确,但我没有收到任何错误。

我的代码是这样工作的:SceneDelegate.swift 将我的 LandmarkList.swift 设置为 rootViewController。然后 LandmarkList 调用 GoogMapView.swift 来显示 Google map 的实例。

SceneDelegate.swift:

我认为我在这里使用 locationManager 可能是错误的?

import UIKit
import SwiftUI
import GoogleMaps
import GooglePlaces
import CoreLocation



class SceneDelegate: UIResponder, UIWindowSceneDelegate, CLLocationManagerDelegate {


var window: UIWindow?
private let locationManager = CLLocationManager()


func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).

// Use a UIHostingController as window root view controller
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: LandmarkList())
self.window = window
window.makeKeyAndVisible()
}

locationManager.requestAlwaysAuthorization()

if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
}

}
}

LandmarkList.swift:

import SwiftUI

struct LandmarkList: View {

@State private var searchText = ""
@State private var locationText = ""


var body: some View {


ZStack(alignment: Alignment.top) {
GoogMapView()
.frame(height: 750)


SlideOverCard {
VStack(alignment: .leading) {
List(landmarkData) { landmark in
NavigationLink(destination: LandmarkDetail(landmark: landmark)) {
LandmarkRow(landmark: landmark)
}
}

}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: Alignment.topLeading)
}
}
}
}

GoogMapView.swift:

注意:下面的打印语句仅返回“用户位置未知”

import SwiftUI
import UIKit
import GoogleMaps
import GooglePlaces
import CoreLocation


struct GoogMapView : UIViewRepresentable {

let marker : GMSMarker = GMSMarker()

//Creates a `UIView` instance to be presented.
func makeUIView(context: Context) -> GMSMapView {
// Create a GMSCameraPosition
let camera = GMSCameraPosition.camera(withLatitude: 42.361145, longitude: -71.057083, zoom: 16.0)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
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

if let mylocation = mapView.myLocation {
print("User's location: \(mylocation)")
} else {
print("User's location is unknown")
}

return mapView
}

// Updates the presented `UIView` (and coordinator) to the latestconfiguration.
func updateUIView(_ mapView: GMSMapView, context: Context) {
// Creates a marker in the center of the map.
marker.position = CLLocationCoordinate2D(latitude: 42.361145, longitude: -71.057083)
marker.title = "Boston"
marker.snippet = "USA"
marker.map = mapView
}
}

同样,我认为 SceneDelegate.swift 中有关 locationManager 的代码将使 GoogleMaps 相机实例在启动时聚焦于用户位置,但事实并非如此。

有人知道我做错了什么吗?

最佳答案

我终于能够弄清楚如何立即关注“我的位置”,而不是要求用户输入。以下是更多详细信息...希望有帮助!

更新UIView

  • 您希望在检索用户位置时调用 updateUIView。据我所知,当 @State@Binding 对象更改(或 @ObservedObject)时,会调用 updateUIView 。因此,UIViewRepresentable 需要具有其中之一。在下面的代码中,我使用 @ObservedObject。每当 @ObservedObject@Published 属性之一发生更改时,updateUIView 将被调用。

创建观察对象

  • 我创建了一个符合 ObservableObject 协议(protocol)的类 (LocationManager)。

  • 在类中,我将 lastKnownLocation 公开为 @Published 属性。如上所述,当更新 lastKnownLocation 时,LocationManager 类实例的任何订阅者都将看到这些更新

获取用户坐标

  • CLLocationManager 用于获取用户位置的更新。

  • 我创建的 LocationManager 类实现了 CLLocationManager

  • 的委托(delegate)函数
  • 当用户的位置更新时,将调用委托(delegate)函数didUpdateLocations。然后,在该函数中,我更新 @Published 属性,以便 UIViewRepresentable 看到这些更改,并相应地自动调用 updateUIView

UIViewRepresentable

import SwiftUI
import GoogleMaps
import Combine

struct HomeView: UIViewRepresentable {

// Listen to changes on the locationManager
@ObservedObject var locationManager = LocationManager()

func makeUIView(context: Self.Context) -> GMSMapView {

// Just default the camera to anywhere (this will be overwritten as soon as myLocation is grabbed
let camera = GMSCameraPosition.camera(withLatitude: 0, longitude: 0, zoom: 16.0)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
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

return mapView
}

func updateUIView(_ mapView: GMSMapView, context: Self.Context) {

// When the locationManager publishes updates, respond to them
if let myLocation = locationManager.lastKnownLocation {
mapView.animate(toLocation: myLocation.coordinate)
print("User's location: \(myLocation)")
}
}
}

LocationManager 类:

class LocationManager: NSObject, CLLocationManagerDelegate, ObservableObject {

// Publish the user's location so subscribers can react to updates
@Published var lastKnownLocation: CLLocation? = nil
private let manager = CLLocationManager()

override init() {
super.init()
self.manager.delegate = self
self.manager.startUpdatingLocation()
}

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .authorizedWhenInUse {
self.manager.startUpdatingLocation()
}
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// Notify listeners that the user has a new location
self.lastKnownLocation = locations.last
}
}

关于swift - 如何使用 swiftUI View 在启动时将 Google map 相机聚焦在用户当前位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58346305/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com