gpt4 book ai didi

SwiftUI mapkit 将区域设置为用户的当前位置

转载 作者:行者123 更新时间:2023-12-02 18:54:11 25 4
gpt4 key购买 nike

我正在使用 Xcode 12。

我能够显示带有区域但带有硬编码值的 map 。

相反,我想根据用户的当前位置设置 map 区域。

我有一个 LocationManager 类,它获取用户的位置并发布它。

我有一个 ShowMapView SwiftUI View ,它观察基于 LocationManager 类的对象以获取用户的位置。但是,我不知道如何使用 locationManager 对象中的数据来设置 map 使用的区域。

这里是 LocationManager 类,它获取用户的位置并发布它。

import Foundation
import MapKit

final class LocationManager: NSObject, ObservableObject {
@Published var location: CLLocation?

private let locationManager = CLLocationManager()

override init() {
super.init()

self.locationManager.delegate = self

self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.distanceFilter = kCLDistanceFilterNone
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
}
}

extension LocationManager: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.last {
self.location = location
}
}
}

这里是ShowMapView SwiftUI View,需要获取用户发布的位置,设置 map 使用的区域。如您所见,这些值目前是硬编码的。

import Combine
import MapKit
import SwiftUI

struct AnnotationItem: Identifiable {
let id = UUID()
let name: String
let coordinate: CLLocationCoordinate2D
}

struct ShowMapView: View {
@ObservedObject private var locationManager = LocationManager()

@State private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 38.898150, longitude: -77.034340),
span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)
)

var body: some View {
Map(coordinateRegion: $region, annotationItems: [AnnotationItem(name: "Home", coordinate: CLLocationCoordinate2D(latitude: self.locationManager.location!.coordinate.latitude, longitude: self.locationManager.location!.coordinate.longitude))]) {
MapPin(coordinate: $0.coordinate)
}
.frame(height: 300)
}
}

最佳答案

这里有一个可能的解决方案:

final class LocationManager: NSObject, ObservableObject {
@Published var location: CLLocation?
@Published var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 38.898150, longitude: -77.034340),
span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)
)
private var hasSetRegion = false

private let locationManager = CLLocationManager()

override init() {
super.init()

self.locationManager.delegate = self

self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.distanceFilter = kCLDistanceFilterNone
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
}
}

extension LocationManager: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.last {
self.location = location

if !hasSetRegion {
self.region = MKCoordinateRegion(center: location.coordinate,
span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5))
hasSetRegion = true
}
}
}
}

struct ShowMapView: View {
@ObservedObject private var locationManager = LocationManager()

var homeLocation : [AnnotationItem] {
guard let location = locationManager.location?.coordinate else {
return []
}
return [.init(name: "Home", coordinate: location)]
}

var body: some View {
Map(coordinateRegion: $locationManager.region, annotationItems: homeLocation) {
MapPin(coordinate: $0.coordinate)
}
.frame(height: 300)
}
}

在此解决方案中,区域由位置管理器发布。一旦接收到位置,该区域就会以该点为中心(在 didUpdateLocations 中)。然后,设置一个 bool 标志,表示该区域最初已居中。设置该 bool 值后,它不再更新该区域。这将使用户仍然可以拖动/缩放等。

我还更改了您的代码以稍微放下 pin。您正在强制展开 location,在第一个位置由位置管理器设置之前它是 nil,导致崩溃。在我的编辑中,如果还没有位置,它只会返回一个空的注释项数组。

关于SwiftUI mapkit 将区域设置为用户的当前位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66411263/

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