2016-12-01 44 views
2

我正在开发一个请求多个方向(MKDirectionsRequest)并在mapView中绘制路线的应用程序,一切正常。Swift:子类MKPolyline

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

第一个想法很简单:使用标题/副标题为“标签”不同MKPolyline,所以我可以设置我想在委托函数的颜色:

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

,而是因为这是我不喜欢这样的解决方案“丑”,我将不得不分析字符串一天我必须通过不同PARAMS(交通..)

第二简单的解决办法是子类MKPolyline,叶简单.. 作为MKPolyline不具有指定初始值设定项,这是不可能的(是吗?)

[编辑]:我想创建一个MKPolyline的子类来复制已经创建的MKDirectionsRequest.routes返回的MKPolyline,但我无法弄清楚如何覆盖只读参数(Apple说我们应该如果正在使用objC,它将很容易在运行时“注入”代码并添加我的参数,但我正在使用swift。

任何人都可以帮助这个,谢谢。

回答

0

为什么要为您的自定义MKOverlay设置颜色,难道您只需将所需颜色设置为MKOverlayRenderer?那应该是比较简单的。

你也可以很容易地继承MKPolyline。我不明白你为什么无法做到这一点。

如果您希望能够创建自定义MKOverlay并设置自定义属性,然后将其绘制到地图中,您还需要创建自己的渲染器。这似乎是一个很大的工作。但是,这是一个例子,你可以做到这一点。

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 
    } 
} 

Result

+0

更新我的问题,所以你可以理解为什么我要继承 –

1

更简单的方法,不需要自定义呈现:

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() 
    } 

} 

ScreenShot