与 MapKit 中的缩放相关的 MKPolyline 奇怪渲染

Posted

技术标签:

【中文标题】与 MapKit 中的缩放相关的 MKPolyline 奇怪渲染【英文标题】:MKPolyline strange rendering related with zooming in MapKit 【发布时间】:2016-10-25 11:08:53 【问题描述】:

我有一个非常简单的视图控制器来演示 MKPolyline 的这种奇怪的渲染行为。没什么特别的,只是普通的 api 调用。

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate 

    @IBOutlet weak var map: MKMapView!

    override func viewDidLoad() 
        super.viewDidLoad()
        map.delegate = self
    

    override func viewDidAppear(_ animated: Bool) 
        super.viewDidAppear(animated)
        let p1 = CLLocationCoordinate2D(latitude: 51, longitude: 13)
        var coords = [
            p1,
            CLLocationCoordinate2D(latitude: 51.1, longitude: 13),
            CLLocationCoordinate2D(latitude: 51.2, longitude: 13),
            CLLocationCoordinate2D(latitude: 51.3, longitude: 13)
        ]

        let polyline = MKPolyline(coordinates: &coords, count: coords.count)
        map.addOverlays([polyline], level: .aboveRoads)
        let cam = MKMapCamera(lookingAtCenter: p1, fromDistance: 1000, pitch: 45, heading: 0)
        map.setCamera(cam, animated: true)
    

    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer 
        let r = MKPolylineRenderer(overlay: overlay)
        r.strokeColor = UIColor.blue
        return r
    

折线的渲染很奇怪。在缩放和平移过程中您可以看到一些伪影。

看看下面的图片:

初始屏幕

经过一些平移

缩小并再次放大后

如何解决这个问题?我试图实现自己的渲染器,但情况相同。就像overaly被缓存并且它没有按时重绘一样。我正在开发 ios 10、iPhone 6、来自 iOS SDK 10 xCode 8 的模拟器。

【问题讨论】:

看到这个答案***.com/questions/20601768/… 我遇到了同样的问题并用这个解决了它:***.com/questions/40087736/… 这个问题没有合适的解决方案,也没有找到解决方案。还有人吗? 由于这个错误,我们选择使用 Google Maps iOS SDK。它在图形和覆盖范围方面要好得多。 大家好.. 最新IOS中上述问题的解决方案是什么 【参考方案1】:

Swift 3 解决方案:

创建 MKPolylineRenderer 的子类

class CustomPolyline: MKPolylineRenderer 

    override func applyStrokeProperties(to context: CGContext, atZoomScale zoomScale: MKZoomScale) 
        super.applyStrokeProperties(to: context, atZoomScale: zoomScale)
        UIGraphicsPushContext(context)
        if let ctx = UIGraphicsGetCurrentContext() 
            ctx.setLineWidth(self.lineWidth)
        
    

然后在您的 rendererFor MapKit 委托中使用它:

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer 
        let renderer = CustomPolyline(overlay: overlay)
        renderer.strokeColor = UIColor.red
        renderer.lineWidth = 100
        return renderer

您的折线在缩放后不会重新渲染,从而避免了伪影

【讨论】:

这确实有效。但请确保将 renderer.lineWidth 设置为较高的值,否则您将看不到折线。我通过设置 ctx.setLineWidth(self.lineWidth * 100) 更改了您的自定义类。这样您就不必在委托方法中设置非常高的值。 在撰写本文时,iOS 11.3.1,此解决方案不起作用。如上图所示,我得到了渲染效果不佳的折线。我正在寻找另一种解决方案 非常感谢。我真的很感激

以上是关于与 MapKit 中的缩放相关的 MKPolyline 奇怪渲染的主要内容,如果未能解决你的问题,请参考以下文章

如何使用滑块更改 mapkit 地图视图缩放级别?

iPhone Mapkit 蓝点/用户位置区域缩放问题

转到/缩放到当前位置功能(MapKit)

MapKit 缩放到用户当前位置

较小的 MapKit 缩放间隔 iPhone

MapKit iPhone显示器Zoom Controls