添加倒圆圈叠加到地图视图

(使用iOS 5和Xcode 4.2。)

我按照这里的说明: http : //developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/LocationAwarenessPG/AnnotatingMaps/AnnotatingMaps.html#//apple_ref/doc/uid/TP40009497-CH6-SW15并使用MKCircle和MKCircleView类在我的MKMapView上添加一个圆形覆盖。

然而,我真正想要的是一个倒圆的覆盖,就像下面的草图中的左侧地图(目前我有一个像右侧的覆盖):

倒置和不倒圆圈草图

对于倒圆,覆盖层应该覆盖整个地图 – 除了可见的圆。

有没有简单的方法来完成这个使用MKCircle / MKCircleView类? 或者我将不得不深入并定义一个自定义覆盖物体/视图?

感谢您的帮助 :)

最好的办法是将MKMapView子类MKMapView然后重写drawRect方法,然后用你想要的颜色在地图上绘制。 然后,每次用户移动时, drawRect都应该通过适当的绘制进行响应。

我有同样的任务,这是我如何解决它:

注意:这个代码只能从iOS7开始

在你的视图控制器的某处添加一个覆盖图到地图上:

 MyMapOverlay *overlay = [[MyMapOverlay alloc] initWithCoordinate:coordinate]; [self.mapView addOverlay:overlay level:MKOverlayLevelAboveLabels]; 

在MKMapViewDelegate方法中写下一个:

 - (MKOverlayRenderer *)mapView:(MKMapView *)map rendererForOverlay:(id<MKOverlay>)overlay { /// we need to draw overlay on the map in a way when everything except the area in radius of 500 should be grayed /// to do that there is special renderer implemented - NearbyMapOverlay if ([overlay isKindOfClass:[NearbyMapOverlay class]]) { MyMapOverlayRenderer *renderer = [[MyMapOverlayRenderer alloc] initWithOverlay:overlay]; renderer.fillColor = [UIColor whateverColor];/// specify color which you want to use for gray out everything out of radius renderer.diameterInMeters = 1000;/// choose whatever diameter you need return renderer; } return nil; } 

MyMapOverlay本身应该如下所示:

 @interface MyMapOverlay : NSObject<MKOverlay> - (instancetype)initWithCoordinate:(CLLocationCoordinate2D)coordinate; @end @implementation MyMapOverlay @synthesize coordinate = _coordinate; - (instancetype)initWithCoordinate:(CLLocationCoordinate2D)coordinate { self = [super init]; if (self) { _coordinate = coordinate; } return self; } - (MKMapRect)boundingMapRect { return MKMapRectWorld; } @end 

和MyMapOverlayRenderer:

 @interface MyMapOverlayRenderer : MKOverlayRenderer @property (nonatomic, assign) double diameterInMeters; @property (nonatomic, copy) UIColor *fillColor; @end @implementation MyMapOverlayRenderer /// this method is called as a part of rendering the map, and it draws the overlay polygon by polygon /// which means that it renders overlay by square pieces - (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context { /// main path - whole area UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(mapRect.origin.x, mapRect.origin.y, mapRect.size.width, mapRect.size.height)]; /// converting to the 'world' coordinates double radiusInMapPoints = self.diameterInMeters * MKMapPointsPerMeterAtLatitude(self.overlay.coordinate.latitude); MKMapSize radiusSquared = {radiusInMapPoints, radiusInMapPoints}; MKMapPoint regionOrigin = MKMapPointForCoordinate(self.overlay.coordinate); MKMapRect regionRect = (MKMapRect){regionOrigin, radiusSquared}; //origin is the top-left corner regionRect = MKMapRectOffset(regionRect, -radiusInMapPoints/2, -radiusInMapPoints/2); // clamp the rect to be within the world regionRect = MKMapRectIntersection(regionRect, MKMapRectWorld); /// next path is used for excluding the area within the specific radius from current user location, so it will not be filled by overlay fill color UIBezierPath *excludePath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(regionRect.origin.x, regionRect.origin.y, regionRect.size.width, regionRect.size.height) cornerRadius:regionRect.size.width / 2]; [path appendPath:excludePath]; /// setting overlay fill color CGContextSetFillColorWithColor(context, self.fillColor.CGColor); /// adding main path. NOTE that exclusionPath was appended to main path, so we should only add 'path' CGContextAddPath(context, path.CGPath); /// tells the context to fill the path but with regards to even odd rule CGContextEOFillPath(context); } 

因此,您将在问题中发布的左侧图像上具有完全相同的视图。

这里有一个Swift版本。 感谢Valerii。

https://github.com/dariopellegrini/MKInvertedCircle