Swift UI-用户位置不集中在MAPKIT上,调整地图跳回位置

发布于 2025-01-24 21:02:48 字数 4614 浏览 4 评论 0原文

我想构建一张显示用户位置,缩放标度的地图,可以在标准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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文