问题
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