How to refresh an MKOverlayRenderer when mapView change

為{幸葍}努か 提交于 2020-01-15 05:36:06

问题


I am new to code, and i'm trying to realize something like Reminders app :

I've follow another answer to realize it and

here my code:

In my ViewController:

var circle = MKCircle(centerCoordinate: location.coordinate, radius: 100)
self.mapView.addOverlay(circle)

In my MKMapView:

func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {

    if overlay is MKCircle
    {
        render = MapFillRenderer(overlay: overlay)
        return render
    } else {
        return nil
    }
}

And the MapFillRenderer (subclass of MKOverlayRenderer):

class MapFillRenderer: MKOverlayRenderer {

    var colorIn: UIColor
    var colorOut: UIColor

    override func drawMapRect(mapRect: MKMapRect, zoomScale: MKZoomScale, inContext context: CGContext!) {
        // Fill full map rect with some color.
        var rect = self.rectForMapRect(mapRect)
        CGContextSaveGState(context);
        CGContextAddRect(context, rect);
        CGContextSetFillColorWithColor(context, colorOut.CGColor)
        CGContextFillRect(context, rect);
        CGContextRestoreGState(context);

        // Clip rounded hole.
        CGContextSaveGState(context);
        CGContextSetFillColorWithColor(context, colorIn.CGColor);
        CGContextSetBlendMode(context, kCGBlendModeClear);
        CGContextFillEllipseInRect(context, self.rectForMapRect(self.overlay.boundingMapRect))
        CGContextRestoreGState(context);

        // Draw circle
        super.drawMapRect(mapRect, zoomScale: zoomScale, inContext: context)
    }
}

The issue:

But I've an issue when the user move the map, the main mask doesn't refresh and it not fill all the map area. Something notable, it refresh, but only when i'm zoom out enough. How can I force it to refresh when user move the map without zoom out? I've try with, but it fail :

    func mapView(mapView: MKMapView!, regionDidChangeAnimated animated: Bool) {
    if render.overlay != nil {
        render.setNeedsDisplay()
    }
}

Thanks for any idea,

Here image of the result when user move the map without zoom:


回答1:


MapKit calls your renderer by tile. To figure out which tiles (expressed in 'MKMapRect's) to render, it asks the MKOverlay if your renderer will render on that tile or not.

MKCircle is very probably implemented in a way that will say yes only to those tiles that contain your circle.

So you need to override var boundingMapRect: MKMapRect { get } to return MKMapRectWorld or override optional func intersectsMapRect(_ mapRect: MKMapRect) -> Bool of MKCircle.

Then your renderer is called for every tile that is shown to the user.

Since MKCircle is mostly about calculating the rect around the circle and checking if a tile will intersect with that rect, it is probably better to implement your own MKOverlay just returning MKMapRectWorld as its boundingMapRec.



来源:https://stackoverflow.com/questions/30544354/how-to-refresh-an-mkoverlayrenderer-when-mapview-change

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!