Swift UI-用户位置不集中在MAPKIT上,调整地图跳回位置
我想构建一张显示用户位置,缩放标度的地图,可以在标准Maptype和Hybrid Maptype之间切换。
出于测试原因,我还没有集成MapStyle-packer。我通过实现map.maptype变量为我提供了帮助,但这不起作用。
我遇到的另一个问题是关于用户位置:我集成了一个位于返回实际位置的位置manager类 - 可行的 - 但是,如果我在地图上滚动或缩放,5秒后,屏幕会跳回用户位置。
如果您能帮助我,我会很高兴。我附上两个文件。
感谢您的帮助!
update
因此,在stackoverflow中搜索后,我找到了这个线程, swiftui mapkit将区域设置为用户当前位置,并将其实现到我的代码中。但是现在我的问题是,当地图以居中视图启动时,我没有看到我的实际位置,我只看到硬编码的位置。
mapmodel.swift
struct MapModel: UIViewRepresentable {
@Binding var region: MKCoordinateRegion
var mapType : MKMapType
var userTracking: MKUserTrackingMode
var showsUserLocation: Bool
// var annotation: GCModel
init(
region: Binding<MKCoordinateRegion>,
mapType: MKMapType,
userTrackingMode: MKUserTrackingMode,
showsUserLocation: Bool = true
// annotation: GCModel = GCModel(title: "", coordinate: CLLocationCoordinate2D(latitude: 0, longitude: 0))
){
self._region = region
self.mapType = mapType
self.userTracking = userTrackingMode
self.showsUserLocation = showsUserLocation
// self.annotation = annotation
}
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.setRegion(region, animated: false)
mapView.mapType = mapType
mapView.showsUserLocation = showsUserLocation
mapView.userTrackingMode = userTracking
mapView.delegate = context.coordinator
// Add annotation to the map
// mapView.addAnnotation(annotation.pointAnnotation)
return mapView
}
func updateUIView(_ mapView: MKMapView, context: Context) {
mapView.mapType = mapType
// Update your region so that it is now your new region
mapView.setRegion(region, animated: false)
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, MKMapViewDelegate {
var parent: MapModel
init(_ parent: MapModel) {
self.parent = parent
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
// We should handle dequeue of annotation view's properly so we have to write this boiler plate.
// This basically dequeues an MKAnnotationView if it exists, otherwise it creates a new
// MKAnnotationView from our annotation.
guard annotation is MKPointAnnotation else { return nil }
let identifier = "Annotation"
guard let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) else {
let annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView.canShowCallout = true
return annotationView
}
annotationView.annotation = annotation
return annotationView
}
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
// We need to update the region when the user changes it
// otherwise when we zoom the mapview will return to its original region
DispatchQueue.main.async {
self.parent.region = mapView.region
}
}
}
}
mapview.swift
struct MapView: View {
@State var trackingMode: MKUserTrackingMode = .follow
@ObservedObject private var managerDelegate = LocationManager()
@State private var mapType: MKMapType = .standard
var body: some View {
VStack {
MapModel(
region: $managerDelegate.region,
mapType: mapType,
userTrackingMode: trackingMode,
showsUserLocation: true
).edgesIgnoringSafeArea([.bottom,.top])
Picker("", selection: $mapType) {
Text("Standard").tag(MKMapType.standard)
Text("Satellite").tag(MKMapType.satellite)
Text("Hybrid").tag(MKMapType.hybrid)
}
.pickerStyle(SegmentedPickerStyle())
.opacity(0.5)
Spacer()
}
}
}
I want to build a map which shows the user location, the zoom scale and can be switched between standard maptype and hybrid maptype.
For testing reasons, I didn't integrate the mapstyle-picker yet. I helped me out by implementing the map.mapType variable, but that doesn't work.
Another problem I have is about the user location: I integrated a LocationManager class which returns the actual position - that works - but if I scroll or zoom on the map, after 5 seconds the screen jumps back to the user location.
I would be glad if you could help me with that. I attach my both files.
Thanks for your help!
UPDATE
So after I searched in stackoverflow I found this thread, SwiftUI mapkit set region to user's current location and implemented these into my code. But now I've the problem, that I didn't see my actual position when the map starts as centered view, I see only the hardcoded one.
MapModel.swift
struct MapModel: UIViewRepresentable {
@Binding var region: MKCoordinateRegion
var mapType : MKMapType
var userTracking: MKUserTrackingMode
var showsUserLocation: Bool
// var annotation: GCModel
init(
region: Binding<MKCoordinateRegion>,
mapType: MKMapType,
userTrackingMode: MKUserTrackingMode,
showsUserLocation: Bool = true
// annotation: GCModel = GCModel(title: "", coordinate: CLLocationCoordinate2D(latitude: 0, longitude: 0))
){
self._region = region
self.mapType = mapType
self.userTracking = userTrackingMode
self.showsUserLocation = showsUserLocation
// self.annotation = annotation
}
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.setRegion(region, animated: false)
mapView.mapType = mapType
mapView.showsUserLocation = showsUserLocation
mapView.userTrackingMode = userTracking
mapView.delegate = context.coordinator
// Add annotation to the map
// mapView.addAnnotation(annotation.pointAnnotation)
return mapView
}
func updateUIView(_ mapView: MKMapView, context: Context) {
mapView.mapType = mapType
// Update your region so that it is now your new region
mapView.setRegion(region, animated: false)
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, MKMapViewDelegate {
var parent: MapModel
init(_ parent: MapModel) {
self.parent = parent
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
// We should handle dequeue of annotation view's properly so we have to write this boiler plate.
// This basically dequeues an MKAnnotationView if it exists, otherwise it creates a new
// MKAnnotationView from our annotation.
guard annotation is MKPointAnnotation else { return nil }
let identifier = "Annotation"
guard let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) else {
let annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView.canShowCallout = true
return annotationView
}
annotationView.annotation = annotation
return annotationView
}
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
// We need to update the region when the user changes it
// otherwise when we zoom the mapview will return to its original region
DispatchQueue.main.async {
self.parent.region = mapView.region
}
}
}
}
MapView.swift
struct MapView: View {
@State var trackingMode: MKUserTrackingMode = .follow
@ObservedObject private var managerDelegate = LocationManager()
@State private var mapType: MKMapType = .standard
var body: some View {
VStack {
MapModel(
region: $managerDelegate.region,
mapType: mapType,
userTrackingMode: trackingMode,
showsUserLocation: true
).edgesIgnoringSafeArea([.bottom,.top])
Picker("", selection: $mapType) {
Text("Standard").tag(MKMapType.standard)
Text("Satellite").tag(MKMapType.satellite)
Text("Hybrid").tag(MKMapType.hybrid)
}
.pickerStyle(SegmentedPickerStyle())
.opacity(0.5)
Spacer()
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论