【问题标题】:swift remove map overlays快速删除地图覆盖
【发布时间】:2014-12-03 13:03:52
【问题描述】:

我正在尝试从地图中删除叠加层。

func removeMapOverlay() {

    var removeOverlays : [AnyObject]! = self.mapView.overlays
    // Above line throws runtime exception

    self.mapView.removeOverlays(removeOverlays)
}

self.mapView.overlaysAnyObject 数组的类型。 var overlays: [AnyObject]! { get }

所以一开始我是这么写的

var removeOverlays = self.mapView.overlays

它在运行时在这一行抛出EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) 异常。

所以我为[AnyObject] 进行了类型转换,我不知道它是否正确,但它在运行时仍然给我同样的异常。

编辑:

我为 Objective C 代码所做的是:

- (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];
}

我尝试在 Swift 中创建类似的方法。但它会引发我上面解释的异常。

【问题讨论】:

  • 确保self.mapView 不是nil
  • @Anna mapview 是一个IBOutlet,它不是零。

标签: ios swift mkmapview mkoverlay


【解决方案1】:

我刚刚这样做了:

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

而且它似乎有效。为什么将叠加层定义为静态变量?

编辑:

这就是我们所做的,以便能够使用全局 contains 函数来搜索 swift 数组并检查我们要查找的元素是否存在于数组中。在本例中,我们在数组中搜索 CLLocationCoordinate2D。

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 {

}

【讨论】:

  • 好的,static 是较早的代码。这段代码对我来说工作得很好。但是看看Objective C代码。挑战在这一行 containsObject 将不起作用,因为 overlays[AnyObject] 参数,我们必须强制转换它。
  • 数组在 swift 中很奇怪。如果您使用的是来自 Objective-C 的 NSArray,您应该可以使用 containsObject,但我不知道它如何转换为新的 Swift 的 AnyObject,因为很确定 NSArray 在后台仍然是 Objective-c。对于 Swift,您可以使用名为 contains() 的全局函数,并且对于其中的对象的可比性,您必须将类扩展为 Equatable 并覆盖 '==' 函数。不要问,这对我来说也很奇怪,但我会编辑我的答案,向您展示我们在快速数组中搜索 CLLocationCoordinate2D 或 MKMapPoint 所做的工作。
  • 你能举个例子,我们如何使用这个Equatable扩展进行比较?
  • 这只是一个想法,它可能不适用于您的情况。但是在 Swift 中似乎能够比较结构或枚举,您需要将它们扩展为可等价的。在答案中检查我上面的编辑。因此,您将 MKUserLocation 扩展为 Equatable。比较是在objective-c中的contains函数中完成的,它是containsObject,在swift中它是一个名为contains的全局函数。
【解决方案2】:

这对我有用:

self.mapView.overlays.forEach {
    if !($0 is MKUserLocation) {
        self.mapView.removeOverlay($0)
    }
}

【讨论】:

    【解决方案3】:

    Import MapKit

    private var appleMapView = MKMapView()

    这里是移除 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)
        }
        
    }
    

    如果您不想删除标记,只需将其称为:

    removeAppleMapOverlays()

    如果您还想删除标记,只需将其称为:

    removeAppleMapOverlays(true)

    【讨论】:

    • 它按预期工作。超级棒。你为我节省了很多时间。再次非常感谢您。
    【解决方案4】:

    对于 google maps iOS 地图(Swift 3 和最新的 iOS SDK)Documentation,您将像这样将叠加层设置为 nil

    overlay.map = nil
    

    【讨论】:

      【解决方案5】:

      以下将实现您的要求:

      mapView.removeOverlays(mapView.overlays)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-23
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-15
        相关资源
        最近更新 更多