2

I'm working on a map-based app. I used a MKTileOverlay to show some dynamic contents. Occasionally certain tiles need reloading when new information arrives.

I've tried to call overlayRenderer.setNeedsDisplayInMapRect(mapRect) in main thread but apparently it doesn't trigger a map redraw in my case. So far the only approach that works is overlayRenderer.reloadData(). However, this will cause the entire contents (instead of only specific region) to be reloaded and lead to flickering in the view, so this is not a option for me.

Can anyone give any advice on this? Thanks & Cheers.

4

1 回答 1

2

最后我想通了。实际上,叠加层没有更新不是由于setNeedsDisplayInMapRect. 经过几次检查后,我发现这setNeedsDisplayInMapRect实际上导致了运行drawMapRect:zoomScale:inContext:,但是,默认重绘会以某种方式生成相同的平铺图像。我猜这可能是由于 MKTileOverlayRender 的一些内部缓存。

我的解决方案是将MKTileOverlayRender, 和在新类中子类化:

override func canDrawMapRect(mapRect: MKMapRect, zoomScale: MKZoomScale) -> Bool {

    let tilePath = self.tilePathForMapRect(mapRect, andZoomScale: zoomScale)
    let tilePathString = stringForTilePath(tilePath)
    if let _ = self.cache.objectForKey(tilePathString) {
        return true
    } else {
        let tileOverlay = self.overlay as! MKTileOverlay
        tileOverlay.loadTileAtPath(tilePath, result: {
            data, error in
            if error == nil && data != nil {
                if let image = UIImage(data: data!) {
                    self.cache.setObject(image, forKey: tilePathString)
                    self.setNeedsDisplayInMapRect(mapRect, zoomScale: zoomScale)
                }
            }
        })

        return false
    }
}

override func drawMapRect(mapRect: MKMapRect, zoomScale: MKZoomScale, inContext context: CGContext) {
    let tilePath = self.tilePathForMapRect(mapRect, andZoomScale: zoomScale)
    let tilePathString = stringForTilePath(tilePath)

    if let image = self.cache.objectForKey(tilePathString) as? UIImage {
        CGContextDrawImage(context, self.rectForMapRect(mapRect), image.CGImage)
    } else {
        super.setNeedsDisplayInMapRect(mapRect, zoomScale: zoomScale)
    }

    self.cache.removeObjectForKey(tilePathString)
}
于 2016-07-01T07:53:53.387 回答