菜鸟教程小白 发表于 2022-12-12 20:57:16

ios - MKTileOverlay:如何重新加载特定的图 block 或区域


                                            <p><p>我正在开发一个基于 map 的应用程序。我使用 <code>MKTileOverlay</code> 来显示一些动态内容。有时,当新信息到达时,某些图 block 需要重新加载。 </p>

<p>我尝试在主线程中调用 <code>overlayRenderer.setNeedsDisplayInMapRect(mapRect)</code> 但显然在我的情况下它不会触发 map 重绘。到目前为止,唯一可行的方法是 <code>overlayRenderer.reloadData()</code>。但是,这将导致重新加载整个内容(而不仅仅是特定区域)并导致 View 闪烁,所以这不是我的选择。</p>

<p>任何人都可以就此提供任何建议吗?谢谢和干杯。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>我终于想通了。事实上,叠加层没有更新并不是由于<code>setNeedsDisplayInMapRect</code>。经过多次检查,我发现 <code>setNeedsDisplayInMapRect</code> 实际上导致了 <code>drawMapRect:zoomScale:inContext:</code> 的运行,但是,默认重绘会以某种方式生成相同的平铺图像。我猜这可能是由于 MKTileOverlayRender 的一些内部缓存。</p>

<p>我的解决方案是继承 <code>MKTileOverlayRender</code>,并在新类中:</p>

<pre><code>override func canDrawMapRect(mapRect: MKMapRect, zoomScale: MKZoomScale) -&gt; 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 &amp;&amp; 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)
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - MKTileOverlay:如何重新加载特定的图 block 或区域,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/38081372/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/38081372/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - MKTileOverlay:如何重新加载特定的图 block 或区域