MKPolyline strange rendering related with zooming in MapKit
Asked Answered
N

1

12

I have very simple View Controller to demonstrate this strange rendering behavior of MKPolyline. Nothing special just normal api calls.

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate {

    @IBOutlet weak var map: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()
        map.delegate = self
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let p1 = CLLocationCoordinate2D(latitude: 51, longitude: 13)
        var coords = [
            p1,
            CLLocationCoordinate2D(latitude: 51.1, longitude: 13),
            CLLocationCoordinate2D(latitude: 51.2, longitude: 13),
            CLLocationCoordinate2D(latitude: 51.3, longitude: 13)
        ]

        let polyline = MKPolyline(coordinates: &coords, count: coords.count)
        map.addOverlays([polyline], level: .aboveRoads)
        let cam = MKMapCamera(lookingAtCenter: p1, fromDistance: 1000, pitch: 45, heading: 0)
        map.setCamera(cam, animated: true)
    }

    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        let r = MKPolylineRenderer(overlay: overlay)
        r.strokeColor = UIColor.blue
        return r
    }
}

The rendering of the polyline is very strange. During zooming and panning You can see some artifacts.

Take a look at pictures below:

Initial Screen Initial Screen

After some panning After some panning

After zooming out and zooming in again After zooming out and zooming in again

How to fix this? I was trying to implement my own renderer but its the same situation. Like overaly is cached and it's not redrawing on time. I'm working on iOS 10, iPhone 6, Simulator from iOS SDK 10 xCode 8.

Noach answered 25/10, 2016 at 11:8 Comment(7)
See this answer #20602268Melanous
i had same problem and fixed it with this: #40088236Mccullum
There is no proper solution for this issue and didn't find solution. anybody else ?Undersexed
Because of this bug we choose to use Google Maps iOS SDK. It is much better in terms of Graphics, and coverage.Noach
Hi Everybody .. What is solution of above problem in Latest IOSGirandole
is there any objective c solution version for this issue.Wool
I'm surprised this is such a common issue with no concrete answer. I've been looking through SO but can't find anything.Vestryman
R
7

Swift 3 solution :

Create a subclass of MKPolylineRenderer

class CustomPolyline: MKPolylineRenderer {

    override func applyStrokeProperties(to context: CGContext, atZoomScale zoomScale: MKZoomScale) {
        super.applyStrokeProperties(to: context, atZoomScale: zoomScale)
        UIGraphicsPushContext(context)
        if let ctx = UIGraphicsGetCurrentContext() {
            ctx.setLineWidth(self.lineWidth)
        }
    }
}

Then use it in your rendererFor MapKit delegate :

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        let renderer = CustomPolyline(overlay: overlay)
        renderer.strokeColor = UIColor.red
        renderer.lineWidth = 100
        return renderer
}

Your polylines won't re-render after zooming thus avoiding the artifacts

Radioactivity answered 25/7, 2017 at 8:47 Comment(3)
This actually works. But make sure that you set your renderer.lineWidth to a high value otherwise you won't see the polyline. I changed your custom class by setting ctx.setLineWidth(self.lineWidth * 100). This way you don't have to set a very high value in the delegate method.Privity
As of this writing, iOS 11.3.1, this solution doesn't work. I got the polyline with a bad rendering as in the picture above. I'm looking for another solutionRamification
Thank you so much. I really appreciatedFlamboyant

© 2022 - 2024 — McMap. All rights reserved.