【问题标题】:Properly subclassing MKOverlayRenderer正确继承 MKOverlayRenderer
【发布时间】:2016-11-05 06:33:23
【问题描述】:

我正在尝试在运行时修改 MKPolyline 的路径以避免它与另一个重叠。

我已经设法得到了所有的重叠点,我想要做的是在 MKPolylineRenderer 的 func createPath() 中添加偏移点,所以,理论上,它应该绘制与我添加的小偏移量相同的路径,它不应该再重叠,但遗憾的是,这没有发生,并且折线以相同的方式绘制,就像没有任何改变一样。

我在 addPolyline() 函数之后第一次尝试这样做,但我读到,一旦你这样做了,重绘折线的一种方法是删除它并再次添加它,所以为了测试目的,我决定这样做所有这些都是在添加折线之前完成的,所以当我最终将它添加到地图时,它已经有了关于重叠点的信息,但这也不起作用。

假设:

1. 地图工作在不同的线程上是有关系的,因此更改不会反映。 没关系。应该是这样优化渲染的。

2。完成此操作的正确方法不在createPath() 函数中。确实不是

  1. 我应该在渲染器的draw() 函数中应用一个transform就是这样

这是 createPath() 函数

override func createPath()
{
   let poly = polyline as! TransportPolyline

   switch poly.id
    {
    case 1:
        let newPath = CGMutablePath()

        for index in 0...poly.pointCount
        {
            let point = poly.points()[index]
            let predicate = { MKMapPointEqualToPoint($0, poly.points()[index]) }
            //This is the offset I should apply
            let offset: CGFloat = overlapsAtPoints.contains(predicate) ? 100000.0 : 0.0
            //I tried to use a transform as well, but the result was the same
            var transform = CGAffineTransform(translationX: offset, y: offset)

            if index == 0
            {
                //Here I add the offset and/or the transform without success
                newPath.moveTo(&transform, x: CGFloat(point.x) + offset, y: CGFloat(point.y) + offset)
            }
            else
            {
                //Here as well
                newPath.addLineTo(&transform, x: CGFloat(point.x) + offset, y: CGFloat(point.y) + offset)
            }
        }

        //Set the new path to the Renderer path property
        self.path = newPath
    default: break
    }
}

这就是draw()函数

override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext)
    {
        let poly = polyline as! TransportPolyline

        guard poly.id == 1 else {
            super.draw(mapRect, zoomScale: zoomScale, in: context)
            return
        }

        //If I apply this the Polyline does move, obviously it move all the Path and not only the segments I want.
        context.translate(x: 1000, y: 1000)

        super.draw(mapRect, zoomScale: zoomScale, in: context)
    }

非常感谢任何建议。

更新:

我发现问题可能在于我如何在 draw 方法中绘制上下文。

文档说:

这个方法的默认实现什么都不做。子类是 期望覆盖此方法并使用它来绘制覆盖的 内容。

所以打电话给super.draw()我什么都没做。

关于如何正确覆盖此方法的任何想法?还要考虑到这一点:

为了提高绘图性能,地图视图可能会划分您的叠加层 分成多个图块并在单独的线程上渲染每个图块。您的 因此,这种方法的实施必须能够安全地 同时从多个线程运行。此外,您应该 避免每次使用此方法绘制覆盖的全部内容 叫做。相反,始终将 mapRect 参数放入 考虑并避免在该矩形之外绘制内容。

【问题讨论】:

    标签: ios iphone swift mapkit mkoverlay


    【解决方案1】:

    所以基本上我是在正确的轨道上,但使用了错误的工具。实现这一点的实际方法是重写 MKPolylineRenderer 子类中的 draw() 函数。

    override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext)
    {
       //First validate that the Rect you are asked to draw in actually 
         has some content. See last quote above.
       let theMapRect: MKMapRect = self.overlay.boundingMapRect;
    
       guard (MKMapRectIntersectsRect(mapRect, theMapRect)) || self.path != nil else {
            return
       }
    
       //Do some logic if needed.
    
       //Create and draw your path
       let path = CGMutablePath()
       path.moveTo(nil, x: self.path.currentPoint.x, y: self.path.currentPoint.y)
       path.addLines(nil, between: remainingPoints, count: remainingPoints.count)
    
       context.addPath(path)
    
       //Customise it
       context.setStrokeColor(strokeColor!.cgColor)
       context.setLineWidth((lineWidth + CGFloat(0.0)) / zoomScale)
    
       //And apply it 
       context.strokePath()
    }
    

    通过这样做,我能够成功地为每个叠加层绘制我想要的路径,而不会遇到任何麻烦。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-13
      • 1970-01-01
      • 2010-11-17
      • 2011-05-03
      • 2017-01-15
      • 2011-04-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多