首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift:子类MKPolyline

Swift:子类MKPolyline
EN

Stack Overflow用户
提问于 2016-12-01 18:46:09
回答 2查看 1.7K关注 0票数 3

我正在开发一个应用程序,请求多个方向(MKDirectionsRequest),并在一个mapView中绘制路线,一切都好。

但我面临着一个问题:我想用不同的颜色绘制每条路线。

第一个想法很简单:使用标题/副标题来‘标记’不同的MKPolyline,这样我就可以在委托函数中设置我想要的颜色:

代码语言:javascript
复制
mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer

但我不喜欢这个解决方案,因为它很“难看”,而且我将不得不解析一个字符串,这一天我将不得不传递不同的参数(流量..)

第二个简单的解决方案是将MKPolyline子类,也就是simple ..由于MKPolyline没有指定的初始化器,这是不可能的(是吗?)

编辑:我想创建一个MKPolyline的子类来复制MKDirectionsRequest.routes返回的已经创建的MKPolyline,但是我不知道如何覆盖只读参数(苹果说我们应该在子类中覆盖它们并添加setter,但我在setter中有一个无限循环,它是..正常)

如果使用的是objC,那么在运行时“注入”代码并添加参数会很简单,但我使用的是swift。

有人能帮个忙吗,谢谢。

EN

回答 2

Stack Overflow用户

发布于 2017-01-06 20:56:28

不需要自定义渲染器的更简单的方法:

代码语言:javascript
复制
import UIKit
import MapKit

class CustomPolyline : MKPolyline {
    var color: UIColor?
}

class ViewController: UIViewController, MKMapViewDelegate {

    @IBOutlet weak var mapView: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // setup mapView
        mapView.delegate = self

        // set map view region
        let location : CLLocationCoordinate2D = CLLocationCoordinate2DMake(51.4987, 0.007);
        let viewRegion = MKCoordinateRegionMakeWithDistance(location, 400, 400)
        mapView.setRegion(viewRegion, animated:true )

        // add red line
        let coords1 = [CLLocationCoordinate2D(latitude: 51.499526, longitude: 0.004785),CLLocationCoordinate2D(latitude: 51.500007, longitude: 0.005493)]
        let polyline1 = CustomPolyline(coordinates: coords1, count: coords1.count)
        polyline1.color = UIColor.red
        mapView.add(polyline1)

        // add blue line
        let coords2 = [CLLocationCoordinate2D(latitude: 51.498103, longitude: 0.007574), CLLocationCoordinate2D(latitude: 51.498190, longitude: 0.009677)]
        let polyline2 = CustomPolyline(coordinates: coords2, count: coords2.count)
        polyline2.color = UIColor.blue
        mapView.add(polyline2)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        if overlay is CustomPolyline {
            let polylineRenderer = MKPolylineRenderer(overlay: overlay)
            polylineRenderer.strokeColor = (overlay as! CustomPolyline).color
            polylineRenderer.lineWidth = 4
            return polylineRenderer
        }
        return MKOverlayRenderer()
    }

}

票数 4
EN

Stack Overflow用户

发布于 2016-12-01 20:29:24

为什么你想要设置你的自定义MKOverlay的颜色,你不能简单地将所需的颜色设置为MKOverlayRenderer吗?那么它应该会非常简单。

您还可以很容易地子类化MKPolyline。我不明白你为什么不能这么做。

如果您希望能够创建自定义MKOverlay并设置自定义属性,然后将其绘制到地图中,则还需要创建自己的渲染器。这似乎是一项艰巨的任务。但是,这里有一个如何做到这一点的例子。

代码语言:javascript
复制
import UIKit
import MapKit


public class CustomOverlay: MKPolyline {
    public var customColor: UIColor?
}


public class CustomRenderer: MKPolylineRenderer {

    override public func strokePath(_ path: CGPath, in context: CGContext) {

        guard let overlayColor = self.overlay as? CustomOverlay, let color = overlayColor.customColor else {
            super.strokePath(path, in: context)
            return
        }

        context.saveGState()
        context.setStrokeColor(color.cgColor)
        context.addPath(path)
        context.drawPath(using: .stroke)
        context.restoreGState()
    }
}


public extension CLLocationCoordinate2D {
    static let Salo = CLLocationCoordinate2DMake(60.3909, 23.1355)
    static let Turku = CLLocationCoordinate2DMake(60.454510, 22.264824)
    static let Helsinki = CLLocationCoordinate2DMake(60.170833, 24.9375)
}


public class ViewController: UIViewController, MKMapViewDelegate {

    private var mapView: MKMapView!

    override public func viewDidLoad() {
        super.viewDidLoad()
        createMapView()
        setupMapView()
    }

    private func createMapView() {
        mapView = MKMapView(frame: .zero)
        mapView.translatesAutoresizingMaskIntoConstraints = false
        mapView.delegate = self
        view.addSubview(mapView)
        [mapView.topAnchor.constraint(equalTo: view.topAnchor),
         mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
         mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
         mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor)].forEach { $0.isActive = true }
    }

    private func setupMapView() {

        let coordinates: [CLLocationCoordinate2D] = [.Helsinki, .Turku]

        let customPolyLine = CustomOverlay(coordinates: coordinates, count: coordinates.count)
        customPolyLine.customColor = UIColor.red
        mapView.add(customPolyLine)

        let coordinateSpan = MKCoordinateSpan(latitudeDelta: 3, longitudeDelta: 3)
        let region = MKCoordinateRegion(center: .Salo, span: coordinateSpan)
        mapView.setRegion(region, animated: true)
    }

    // MARK: MKMapViewDelegate

    public func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {

        /* return a simple renderer */
//        let renderer =  MKPolylineRenderer(overlay:overlay)
//        renderer.lineWidth = 2
//        renderer.lineDashPattern = [1, 2, 1]
//        renderer.strokeColor = UIColor.red
//        return renderer

        /* a custom renderer */
        let customRenderer = CustomRenderer(overlay: overlay)
        customRenderer.lineWidth = 2
        customRenderer.strokeColor = UIColor.green // this color is not used, since we apply color from overlay inside strokePath(:inContext:) method for custom renderer

        customRenderer.lineDashPattern = [1, 2, 1]
        return customRenderer
    }
}

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40908573

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档