'UIViewRepresentable wrapped UIKit Map jumps back on moving
I'm trying to draw routes on a map and I had to come to the conclusion that this is not yet possible with SwiftUI. Many tutorials suggested wrapping the old MKMapVIew into a UIViewRepresentable which seems to work fine but I have one problem.
Because I need to be able to change the region from outside, I've added this line into the updateUIView method but this causes issues when I'm moving the map. I think what happens is when I scroll the map it updates the state but it does not do it for all the frames of the movements so when this updated region 'comes back' through the updateUIView method, my map is already in an other position so it jumps back.
How can I only update the region when it is intended?
Here is my code:
struct CustomMap: UIViewRepresentable{
typealias UIViewType = MKMapView
@Binding var region: MKCoordinateRegion
var onMapTaped: ((_ item: MKMapItem) -> Void)?
private let mapview: MKMapView = MKMapView()
func makeUIView(context: Context) -> MKMapView {
mapview.delegate = context.coordinator
mapview.setRegion(region, animated: true)
mapview.showsUserLocation = true
mapview.addGestureRecognizer(context.coordinator.tapRecognizer)
return mapview
}
func updateUIView(_ uiView: MKMapView, context: Context) {
uiView.setRegion(region, animated: false)
}
func makeCoordinator() -> MapViewCoordinator {
return MapViewCoordinator(customMapView: self)
}
class MapViewCoordinator: NSObject, MKMapViewDelegate{
let customMapView: CustomMap
var tapRecognizer: UITapGestureRecognizer = UITapGestureRecognizer()
init(customMapView: CustomMap){
self.customMapView = customMapView
super.init()
self.tapRecognizer = UITapGestureRecognizer(target:self, action: #selector(tapOnMap))
}
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
DispatchQueue.main.async {
self.customMapView.region = mapView.region
}
}
}
}
Solution 1:[1]
No the most elegant solution in my opinion but it seems like there is no better one at the time. I got the inspiration from @Asperi's comment.
I passed a closure to the initializer of my view that accepts an MKMapView . I save that map view in my state so I can update the region on a button tap or whenever I want.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Chrys |
