我有一个MKMapView
,我想要将地图的某些部分变灰。更具体地说,我希望有一些正常显示的圆和矩形,地图的其余部分有一个半透明的灰色层。像这样:
为此,我认为我应该继承MKOverlay
和MKOverlayRenderer
。正如Apple建议的那样,在我的MKOverlayRenderer
子类中,我应该覆盖drawMapRect:zoomScale:inContext:
方法,并使用Core Graphics绘制我的东西。我的问题是如何使用Core Graphics绘制以下内容?
我花了几个小时看着使用Core Graphics进行屏蔽和剪辑,但我没有发现任何类似的东西。 QuartzDemo有一些剪切和屏蔽的例子。我想用偶数或非零绕组数规则进行裁剪对我来说不起作用,因为矩形和圆形是动态的。我想我必须以某种方式创建一个面具,但我无法弄清楚如何。 QuartzDemo creates a mask out of an image。我怎么能用矩形和圆圈创建一个蒙版?还有其他方法可以解决这个问题吗?
谢谢
答案 0 :(得分:0)
您应该能够设置具有透明度的上下文,绘制粗糙的矩形和圆圈而不抚摸它们,在整个上下文周围绘制一个矩形边框,然后用较暗的颜色填充形状。您需要调查fill order rules以确保更大的空间是填充的而不是较小的连接形状。
我认为使用偶数或非零绕组数规则的剪辑对我来说不起作用,因为矩形和圆形是动态的。
这不重要。
答案 1 :(得分:0)
好吧,我自己做了。我必须创建自己的面具。这是通过绘制“孔”形状,将其输出到ImageRef,并反转此ImageRef以输出蒙版来完成的。如果您在QuartzClipping.m
项目> QuartzClippingView
- > drawInContext
类中添加-(void)drawInContext:(CGContextRef)context {
// ...
CGContextSaveGState(context);
// dimension of the square mask
int dimension = 20;
// create mask
UIGraphicsBeginImageContextWithOptions(CGSizeMake(dimension, dimension), NO, 0.0f);
CGContextRef newContext = UIGraphicsGetCurrentContext();
// draw overlapping circle holes
CGContextFillEllipseInRect(newContext, CGRectMake(0, 0, 10, 10));
CGContextFillEllipseInRect(newContext, CGRectMake(0, 7, 10, 10));
// draw mask
CGImageRef mask = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext());
UIGraphicsEndImageContext();
// the inverted mask is what we need
CGImageRef invertedMask = [self invertMask:mask dimension:dimension];
CGRect rectToDraw = CGRectMake(210.0, height - 290.0, 90.0, 90.0);
// everything drawn in rectToDraw after this will have two holes
CGContextClipToMask(context, rectToDraw, invertedMask);
// drawing a red rectangle for this demo
CGContextFillRect(context, rectToDraw);
CGContextRestoreGState(context);
}
// taken from the QuartzMaskingView below
- (CGImageRef)invertMask:(CGImageRef)originalMask dimension:(int)dimension{
// To show the difference with an image mask, we take the above image and process it to extract
// the alpha channel as a mask.
// Allocate data
NSMutableData *data = [NSMutableData dataWithLength:dimension * dimension * 1];
// Create a bitmap context
CGContextRef context = CGBitmapContextCreate([data mutableBytes], dimension, dimension, 8, dimension, NULL, (CGBitmapInfo)kCGImageAlphaOnly);
// Set the blend mode to copy to avoid any alteration of the source data
CGContextSetBlendMode(context, kCGBlendModeCopy);
// Draw the image to extract the alpha channel
CGContextDrawImage(context, CGRectMake(0.0, 0.0, dimension, dimension), originalMask);
// Now the alpha channel has been copied into our NSData object above, so discard the context and lets make an image mask.
CGContextRelease(context);
// Create a data provider for our data object (NSMutableData is tollfree bridged to CFMutableDataRef, which is compatible with CFDataRef)
CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((__bridge CFMutableDataRef)data);
// Create our new mask image with the same size as the original image
return CGImageMaskCreate(dimension, dimension, 8, 8, dimension, dataProvider, NULL, YES);
}
方法的末尾,则可以使用以下代码段。
{{1}}
欢迎任何更简单/更有效的解决方案:)