使用 Mapkit 的连续用户中心
continuous center of user with Mapkit
下午好,
我在显示地图时遇到问题,因为它只以用户为中心,并且会随着用户移动而停留在用户身上。我的错误出现在我标记 //HERE.
的视图文件中
我的错误是类型 '()' 不符合 'View'
为什么这一行给我一个错误?如果那行 运行s,我的假设是地图区域正在改变,但它仍然会 return 符合的地图。查看文件如下。
如果我 运行 它没有注释行,它不会显示我的当前位置。我将我的模拟器设置设置为功能 > 位置 > Apple。即使我正在缩小,地图上也没有任何标记。
import SwiftUI
import MapKit
struct Location: Identifiable {
let id = UUID()
let name: String
let content: String?
let lat: Double
let lon: Double
var dangerLevel: CGFloat? = 10.0
var coord: CLLocationCoordinate2D { CLLocationCoordinate2D(latitude: lat, longitude: lon) }
}
struct ContentView: View {
@EnvironmentObject var locationManager: LocationManager
@State private var userTrackingMode: MapUserTrackingMode = .follow
@State var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 40.7128, longitude: 74.0060), span: MKCoordinateSpan( latitudeDelta: 0.03, longitudeDelta: 0.03))
var body: some View {
var locationManager = LocationManager()
region = MKCoordinateRegion(center: locationManager.location!.coordinate, span: MKCoordinateSpan( latitudeDelta: 0.03, longitudeDelta: 0.03)) // HERE!!!!
VStack {
Map(coordinateRegion: $region,
interactionModes: .all,
showsUserLocation: true)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(LocationManager())
}
}
这是我定义 locationManager 的下一个文件
import Foundation
import CoreLocation
class LocationManager: NSObject, ObservableObject {
private let locationManager = CLLocationManager()
@Published var location: CLLocation?
override init() {
super.init()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
}
}
extension LocationManager : CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
self.location = location
}
}
您的代码存在一些问题。首先,要回答提出的问题,您应该避免将不是视图的变量直接放入 var body
。虽然有办法绕过这个限制,但没有充分的理由再绕过。由于 region
不是视图,代码通过错误。是的,我知道您定义了 var locationManager
并且 ViewBuilder
将其视为变量的初始化,而不是变量本身。但是,您已经引用了在 header 中定义的 locationManager
。用那个。
我对您的代码进行了一些更改,并添加了注释以帮助解决问题。如果您还有其他问题,请告诉我。
struct ContentView: View {
// Unless you are using locationManager all over your code, you don't need to pass it as an
// .environmentObject, though you can if needed. Since this is the first instance in this example
// of locationManager, I made it a @StateObject.
@StateObject var locationManager = LocationManager()
@State private var userTrackingMode: MapUserTrackingMode = .follow
@State var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 37.60697453, longitude: -122.42798519), span: MKCoordinateSpan( latitudeDelta: 0.03, longitudeDelta: 0.03))
var body: some View {
VStack {
Map(coordinateRegion: $region,
interactionModes: .all,
showsUserLocation: true)
// Since locationManager is an ObservableObject, you can watch for changes with .onChange(of:)
.onChange(of: locationManager.location) { newLocation in
// Never force unwrap an optional unless you just set it yourself in the code.
guard let newLocation = newLocation else { return }
region = MKCoordinateRegion(center: newLocation.coordinate, span: MKCoordinateSpan( latitudeDelta: 0.03, longitudeDelta: 0.03)) // HERE!!!!
}
}
}
}
import CoreLocation
// I would consider renaming this class. It can be confusing to see
// locationManager.locationManager in code.
class LocationManager: NSObject, ObservableObject {
private let locationManager = CLLocationManager()
@Published var location: CLLocation?
override init() {
super.init()
// You can generally drop .self, with some exceptions. The compiler will correct you.
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
}
extension LocationManager : CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
// This is an exception to dropping self when a variable in a closure has the same name as a
// self variable.
self.location = location
}
}
下午好,
我在显示地图时遇到问题,因为它只以用户为中心,并且会随着用户移动而停留在用户身上。我的错误出现在我标记 //HERE.
的视图文件中我的错误是类型 '()' 不符合 'View'
为什么这一行给我一个错误?如果那行 运行s,我的假设是地图区域正在改变,但它仍然会 return 符合的地图。查看文件如下。
如果我 运行 它没有注释行,它不会显示我的当前位置。我将我的模拟器设置设置为功能 > 位置 > Apple。即使我正在缩小,地图上也没有任何标记。
import SwiftUI import MapKit struct Location: Identifiable { let id = UUID() let name: String let content: String? let lat: Double let lon: Double var dangerLevel: CGFloat? = 10.0 var coord: CLLocationCoordinate2D { CLLocationCoordinate2D(latitude: lat, longitude: lon) } } struct ContentView: View { @EnvironmentObject var locationManager: LocationManager @State private var userTrackingMode: MapUserTrackingMode = .follow @State var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 40.7128, longitude: 74.0060), span: MKCoordinateSpan( latitudeDelta: 0.03, longitudeDelta: 0.03)) var body: some View { var locationManager = LocationManager() region = MKCoordinateRegion(center: locationManager.location!.coordinate, span: MKCoordinateSpan( latitudeDelta: 0.03, longitudeDelta: 0.03)) // HERE!!!! VStack { Map(coordinateRegion: $region, interactionModes: .all, showsUserLocation: true) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView().environmentObject(LocationManager()) } }
这是我定义 locationManager 的下一个文件
import Foundation
import CoreLocation
class LocationManager: NSObject, ObservableObject {
private let locationManager = CLLocationManager()
@Published var location: CLLocation?
override init() {
super.init()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
}
}
extension LocationManager : CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
self.location = location
}
}
您的代码存在一些问题。首先,要回答提出的问题,您应该避免将不是视图的变量直接放入 var body
。虽然有办法绕过这个限制,但没有充分的理由再绕过。由于 region
不是视图,代码通过错误。是的,我知道您定义了 var locationManager
并且 ViewBuilder
将其视为变量的初始化,而不是变量本身。但是,您已经引用了在 header 中定义的 locationManager
。用那个。
我对您的代码进行了一些更改,并添加了注释以帮助解决问题。如果您还有其他问题,请告诉我。
struct ContentView: View {
// Unless you are using locationManager all over your code, you don't need to pass it as an
// .environmentObject, though you can if needed. Since this is the first instance in this example
// of locationManager, I made it a @StateObject.
@StateObject var locationManager = LocationManager()
@State private var userTrackingMode: MapUserTrackingMode = .follow
@State var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 37.60697453, longitude: -122.42798519), span: MKCoordinateSpan( latitudeDelta: 0.03, longitudeDelta: 0.03))
var body: some View {
VStack {
Map(coordinateRegion: $region,
interactionModes: .all,
showsUserLocation: true)
// Since locationManager is an ObservableObject, you can watch for changes with .onChange(of:)
.onChange(of: locationManager.location) { newLocation in
// Never force unwrap an optional unless you just set it yourself in the code.
guard let newLocation = newLocation else { return }
region = MKCoordinateRegion(center: newLocation.coordinate, span: MKCoordinateSpan( latitudeDelta: 0.03, longitudeDelta: 0.03)) // HERE!!!!
}
}
}
}
import CoreLocation
// I would consider renaming this class. It can be confusing to see
// locationManager.locationManager in code.
class LocationManager: NSObject, ObservableObject {
private let locationManager = CLLocationManager()
@Published var location: CLLocation?
override init() {
super.init()
// You can generally drop .self, with some exceptions. The compiler will correct you.
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
}
extension LocationManager : CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
// This is an exception to dropping self when a variable in a closure has the same name as a
// self variable.
self.location = location
}
}