2012-01-29 60 views
8

添加倒圆叠加到地图视图

我在这里跟着指示(使用的是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和使用的MKCircleMKCircleView类我MKMapView添加一个圆圈覆盖。

但是我真正想要的是一个倒圆覆盖,就像在下面的草图左侧地图(目前我有一个圆圈重叠像右边的一个):

Inverted and not-inverted circle overlay sketches

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

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

谢谢您的帮助:)

回答

5

做到这一点,最好的办法是子类MKMapView和覆盖drawRect方法调用超,然后画在你想要的颜色的地图。 然后每次用户移动时,drawRect应通过适当的绘制进行响应。

+0

您能否请您建议您在drawRect方法中如何书写? – HarshIT 2015-02-05 06:44:48

+0

在整个地图上绘画也会使区域之间绘制,但他不想要它。答案如何被接受? – 2015-08-25 09:31:10

6

我有同样的任务,这是我如何解决这个问题:

注:此代码只会工作从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); 
} 

因此,您将不得不像被张贴在这个问题在左图像上完全相同的看法。