swift remove map overlays
Asked Answered
B

5

7

I am trying to remove overlays from map.

func removeMapOverlay() {
    
    var removeOverlays : [AnyObject]! = self.mapView.overlays
    // Above line throws runtime exception

    self.mapView.removeOverlays(removeOverlays)
}

self.mapView.overlays are type of AnyObject array. var overlays: [AnyObject]! { get }.

So initially I wrote

var removeOverlays = self.mapView.overlays

It throws EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) exception at this line on runtime.

So I did type casting for [AnyObject] I don't know it is correct or not but it still gives me same exception at runtime.

Edit:

What I did for Objective C code was:

- (void) removeMapOverlay {
    [self.mapView removeOverlays:[self.mapView overlays]];
    
    NSMutableArray *tempArray = [NSMutableArray arrayWithArray:[self.mapView annotations]];
    if ([tempArray containsObject:[MKUserLocation class]]) {
        [tempArray removeObject:[MKUserLocation class]];
    }
    
    NSArray *annotationArray = [NSArray arrayWithArray:tempArray];
    tempArray = nil;
    [self.mapView removeAnnotations:annotationArray];
}

I tried to create similar method in Swift. But it throws an exception like I explain above.

Bilyeu answered 3/12, 2014 at 13:3 Comment(2)
Make sure self.mapView is not nil.Piggyback
@Anna mapview is an IBOutlet and it's not nil.Bilyeu
H
31

I've just done this:

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

and it seems to work. Why do you define your overlays as a static variable?

EDIT:

This is what we've done to be able to use the global contains function to search a swift array and check if the element we're looking for exists inside the array or not. In this case we were searching for CLLocationCoordinate2D inside an array.

public func == (lhs: CLLocationCoordinate2D, rhs: CLLocationCoordinate2D) -> Bool {
return lhs.longitude == rhs.longitude && lhs.latitude == rhs.latitude
}

public func == (lhs: MKMapPoint, rhs: MKMapPoint) -> Bool {
    return lhs.x == rhs.x && lhs.y == rhs.y
}

extension CLLocationCoordinate2D: Equatable{

}

//This is needed to be Equatable to use the global contains function
extension MKMapPoint: Equatable {

}
Halmahera answered 8/12, 2014 at 18:25 Comment(4)
Ok, static was earlier code. This code was working fine to me. But have a look on Objective C code. Challenge was at this line containsObject will not work because overlays are [AnyObject] parameter and we have to cast it.Bilyeu
Arrays are weird in swift. If you're using an NSArray which is from Objective-C you should be able to use containsObject but I don't know how that translates to new Swift's AnyObject because pretty sure NSArray is still objective-c in the background. For Swift you can use the global function called contains() and for the comparability of objects within it you'd have to do extend a class to be Equatable and override the '==' function. Don't ask, it's really weird to me too but I'll edit my answer to show you what we've done for searching CLLocationCoordinate2D or a MKMapPoint in a swift Array.Halmahera
Can you please give an example, how we can use this Equatable extension for comparison?Bilyeu
It's just an idea, it may not work in your case. But it seems in Swift to be able to compare structs or enums, you need to extend them to be equatable. Check my edit above in the answer. So you'd extend MKUserLocation to be Equatable. The comparison is done in the contains function in objective-c it was containsObject, in swift it's a global function called contains.Halmahera
M
4

This worked for me:

self.mapView.overlays.forEach {
    if !($0 is MKUserLocation) {
        self.mapView.removeOverlay($0)
    }
}
Mayst answered 22/1, 2016 at 16:34 Comment(0)
M
2

Import MapKit

private var appleMapView = MKMapView()

Here is the function to remove MKMapView Overlays + Annotations (Markers)

◙ func removeAppleMapOverlays(_ shouldRemoveMarkers : Bool? = false) {
    let overlays = self.appleMapView.overlays
    self.appleMapView.removeOverlays(overlays)
    if shouldRemoveMarkers == true {
        let annotations = self.appleMapView.annotations.filter {
            $0 !== self.appleMapView.userLocation
        }
        self.appleMapView.removeAnnotations(annotations)
    }
    
}

if you don't want to remove Markers, just call it as:

removeAppleMapOverlays()

and if you want to remove markers also, just call it as:

removeAppleMapOverlays(true)

Maishamaisie answered 27/11, 2020 at 13:40 Comment(1)
It's working as expected. Super awesome. You saved my hell lot of time. Once again thank you so much.Starks
L
1

For google maps iOS mapping (Swift 3 and latest iOS SDK), Documentation, you will set the overlay as nil like so

overlay.map = nil
Lyssa answered 9/5, 2017 at 16:43 Comment(0)
R
1

The following will achieve what you're requesting:

mapView.removeOverlays(mapView.overlays)
Radio answered 24/2, 2020 at 0:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.