iosmapkitmkmapviewmkmapviewdelegate

Overriding MKMapView scroll/pan has very poor performance


I want to restrict the panning of an MKMapView to horizontal/longitude scrolling only.

I set the latitude I want to keep in a var:

var currentLatitude: CLLocationDegrees?

Then I override the mapViewDidChangeVisibleRegion delegate method to reset the map to the latitude if it's changed. It works, however the panning performance is horrible.

    func mapViewDidChangeVisibleRegion(_ mapView: MKMapView) {
        
        let coordinates = CLLocationCoordinate2D(latitude: currentLatitude ?? mapView.region.center.latitude, longitude: mapView.region.center.longitude)
        let newRegion = MKCoordinateRegion(center: coordinates, span: mapView.region.span)
        mapView.setRegion(newRegion, animated: false)
    }

I tried using the same code in regionDidChangeAnimated which works, however it allows vertical panning then when the users finger is lifted off it jumps back to the correct latitude.

There's also regionWillChangeAnimated but I don't believe this gives you the new coordinates before it changes.


Solution

  • Try setting the CameraBoundary for the MKMapView with a latitudinal span of zero and maximum longitudinal span, for example:

    let coordinateRegion =  MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.5072, longitude: -0.1276),
                                               latitudinalMeters: 0,
                                               longitudinalMeters: .greatestFiniteMagnitude)
    
    let boundary = MKMapView.CameraBoundary(coordinateRegion: coordinateRegion)
    
    mapView.setCameraBoundary(boundary, animated: false)