1

I'm currently doing a project which involves mapView that needs to show a line that connects two points and circle around the user's location.

My code goes like this:

self.mapView.delegate = self // on viewDidLoad

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    switch overlay {
    case is MKCircle:
        let circle = MKCircleRenderer(overlay: overlay)
        circle.strokeColor = UIColor.blue
        //            circle.fillColor = UIColor(red: 0, green: 0, blue: 255, alpha: 0.1)
        circle.fillColor = UIColor.blue
        circle.lineWidth = 0.5
        circle.alpha = 0.1
        return circle
    case is MKPolyline:
        let polylineRenderer = MKPolylineRenderer(overlay: overlay)
        polylineRenderer.strokeColor = UIColor.black
        polylineRenderer.lineWidth = 2
        return polylineRenderer
    default:
        return MKPolygonRenderer()
    }
}

func createCircle(location: CLLocation){
    let circle = MKCircle(center: location.coordinate, radius: 500 as CLLocationDistance)
    self.mapView.add(circle)
}

func createPolyline() {
    var coords = [CLLocationCoordinate2D]()
    coords.append(point1)
    coords.append(point2)

    let polyline = MKPolyline(coordinates: coords, count: coords.count)
    self.mapView.add(polyline)
}

createCircle() and createPolyline() is called whenever the location changes so that it will also move to where the user is, my problem is that the previous overlays are kept, and the new ones overlap them. I've found a way to remove an overlay,

let overlays = mapView.overlays
mapView.removeOverlays(overlays)

But this line of code removes all the overlay, I only want to remove, for example, the previous Circle Overlay. Cant find a way to, for example, name a overlay so that I can have a reference to it when removing. Hope I was able to explain my situation well.

What's is the best way to solve this? Thanks!

Lysdexia
  • 453
  • 8
  • 22
  • You can simply `remove` the relevant overlay https://developer.apple.com/reference/mapkit/mkmapview/1451921-remove – Paulw11 May 04 '17 at 07:49
  • @Paulw11 di you mean like this mapView.remove(MKCircle())? I've tried this but it does not remove it. Maybe calling this on a wrong time? – Lysdexia May 04 '17 at 07:56
  • No, that would remove a "new" overlay. you need to keep a reference to the MKOverlay that your originally added. Use a property – Paulw11 May 04 '17 at 07:56
  • a property like what? sorry i have no idea – Lysdexia May 04 '17 at 07:57

3 Answers3

3

You need to store your original MKOverlay object in a property, then you can simply call remove to remove it:

class MyViewController: UIViewController {

    var circle: MKOverlay?

    func createCircle(location: CLLocation){

        self.removeCircle()

        self.circle = MKCircle(center: location.coordinate, radius: 500 as CLLocationDistance)
        self.mapView.add(circle!)
    }

    func removeCircle() {
        if let circle = self.circle {
            self.mapView.remove(circle)
            self.circle = nil
        }
    }
}
Paulw11
  • 108,386
  • 14
  • 159
  • 186
  • hey Paul, I did exactly like this one, but my problem still persists. Multiple overlay is being created. – Lysdexia May 04 '17 at 08:49
  • Is it the circle or the polyline? How are you adding the overlay? I just tested this code and it works correctly for a single circle overlay – Paulw11 May 04 '17 at 09:01
  • with this solution, it works for the circle overlay. I tried this on the polyline too, but it still create multiple overlay. is there any difference between the two? I'm adding it like this polyline = MKPolyline(coordinates: coords, count: coords.count) self.mapView.add(polyline!) – Lysdexia May 04 '17 at 09:04
  • How many polyline segments do you want to keep? How are you tracking and adding/removing them? – Paulw11 May 04 '17 at 09:05
  • Just a single line will do. Whenever the locationManager changes, i want them to change too. So for example, the locationManager calls createPolyline, inside, I will remove then add just like what you showed. – Lysdexia May 04 '17 at 09:07
  • Ok, but if you only keep the most recent polyline, it is going to be very short. – Paulw11 May 04 '17 at 09:08
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/143371/discussion-between-cuevas-and-paulw11). – Lysdexia May 04 '17 at 09:09
2

I run into the same problem. If you want remove only a specific overlay from MKMapView you can do it like this:

// Get the all overlays from map view
if let overlays = mapView?.overlays {
    for overlay in overlays {
        // remove all MKPolyline-Overlays
        if overlay is MKPolyline {
            mapView?.removeOverlay(overlay)
        }
    }
}
Klaus
  • 21
  • 2
0

You should keep the reference for your overlays via property. So every time you create a new overlay (either circle or polyline) you have to remove the old ones. You can create several properties for each overlay or you can keep an array of overlays for specific scenario. I mean, if in some specific case you have to work with several overlay instances, you should keep the array. Anyway, everything depends on concrete situation!