MapKit中2000+注释的最佳实践

时间:2014-12-01 17:19:45

标签: ios xcode swift xcode6 mapkit

我有一个JSON文件,当地图摄像机高度低于750米时,我需要在地图上显示大约2,000个位置。这是我目前的代码:

func addStops() {
    var path: String! = NSBundle.mainBundle().pathForResource("stops", ofType: "json")
    var jsonData: NSData! = NSData(contentsOfFile: path)
    var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
    self.busStops = jsonResult["results"] as NSArray

    for (var i = 0; i < self.busStops.count; i++) {
        let lat = self.busStops[i]["latitude"] as NSString
        let lng = self.busStops[i]["longitude"] as NSString

        var annotation = busAnno()
        annotation.setCoordinate(CLLocationCoordinate2DMake(CLLocationDegrees(lat.doubleValue), CLLocationDegrees(lng.doubleValue)))
        annotation.type = "stop"
        self.mapView.addAnnotation(annotation)
    }
}

注释视图委托:

func mapView (mapView: MKMapView!, viewForAnnotation annotation: MKPointAnnotation!) -> busMarker! {
    var pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: "point")
    pinView.location = annotation.location
    pinView.hidden = true
    pinView.layer.hidden = true
    pinView.enabled = false
}

我认为只是隐藏视图就可以逃脱,但是在应用程序添加标记之后甚至需要响应才需要20秒,然后无法顺畅地移动地图(降低到每秒约5帧) )。

所以,如果我不能那样做,那么更好的方法是什么?我猜测每次地图移动时检查一对坐标是否在屏幕边界内都会因滞后而无法正常工作(基于每次检查2000坐标)。有什么想法吗?

修改

你只会看到2000年的10个注释,因为你必须非常放大才能看到任何注释。这只是我使用哪种方法快速查找区域中的注释而没有这种可怕的延迟的情况。

2 个答案:

答案 0 :(得分:4)

您可以轻松地向MKMapView添加约1,000个注释。看看这个示例项目,增加了3,000:

https://github.com/incanus/PointTest

您可以采取一些措施来改善这项工作。

  1. 只需使用MKPointAnnotation,您就不必手动提供视图。

  2. 如果确实需要自定义视图,则应正确使用重用标识符。您当前正在为每个注释创建一个新视图,实际上您可以一次又一次地重复使用类似视图以获得更高的性能。

  3. 您正在主UI线程中解析和添加注释,这会影响触摸响应性能。请参阅上面的项目,了解在Grand Central Dispatch的后台执行此操作的方法,同时仍然在主UI线程中实际添加注释(所有这些,我可能会添加)。

  4. 您无需担心注释是否在屏幕上。 MapKit为您完成此操作,这就是为什么它在委托回调中查询视图而不是在前端查询。

    以下链接不再有效(2017年10月)

    这是一部关于iPhone 5s上3000个注释的视频:

    https://dl.dropboxusercontent.com/u/575564/3000points.mov

答案 1 :(得分:2)

很抱歉,我发布评论太新了,所以我会在这里回答你关于正确使用重用标识符的问题。

你基本上想要替换:

var pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: "point")

使用:

var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier("point")
if pinView != nil {
    pinView.annotation = annotation;
} else {
    pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: "point")
}