iOS UIView子类,将透视文本绘制到背景

我想在UIView的子类上绘制文本,这样文本就被剪切掉了,并且视图背后的背景显示出来,就像在这里find的OSX Mavericks标志一样。

我会说,我更像是一个中级/早期的高级iOS开发人员,所以随时可以给我一些疯狂的解决scheme。 我希望我不得不重写drawRect为了做到这一点。

多谢你们!

编辑:

我应该提到,我的第一个尝试是使文本[UIColor clearColor]这是行不通的,因为它只是将文本的alpha分量设置为0,它只是显示了文本的视图。

免责声明:我正在写这个没有testing,所以原谅我,如果我在这里错了。

你应该通过以下两个步骤来实现你所需要的:

  1. 用你的视图的大小创build一个CATextLayer ,设置backgroundColor是完全透明的并且foregroundColor是不透明的[UIColor colorWithWhite:0 alpha:1]通过[UIColor colorWithWhite:0 alpha:1][UIColor colorWithWhite:0 alpha:0] 。然后设置string属性为要渲染的string, fontfontSize

  2. 将视图的图层蒙版设置为这个图层: myView.layer.mask = textLayer 。 你将不得不导入QuartzCore来访问你的视图的CALayer

请注意,在第一步中,我可能会在不透明和透明颜色之间切换。

编辑:的确,诺亚是对的。 为了克服这个问题,我使用了CoreGraphics和kCGBlendModeDestinationOut混合模式。

首先是一个示例视图,显示它确实有效:

 @implementation TestView - (id)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { self.backgroundColor = [UIColor clearColor]; } return self; } - (void)drawRect:(CGRect)rect { [[UIColor redColor] setFill]; UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:10]; [path fill]; CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSaveGState(context); { CGContextSetBlendMode(context, kCGBlendModeDestinationOut); [@"Hello!" drawAtPoint:CGPointZero withFont:[UIFont systemFontOfSize:24]]; } CGContextRestoreGState(context); } @end 

添加到你的视图控制器后,你会看到TestView背后的视图, Hello! 画了。

为什么这个工作:

混合模式被定义为R = D*(1 - Sa) ,这意味着我们需要相反的alpha值比在我之前build议的mask层。 因此,所有你需要做的就是绘制一个不透明的颜色,这将从你在视图上预先绘制的东西中减去。

我真的想出了如何自己做出惊人的,但@ StatusReport的答案是完全有效的,现在的工作。

以下是我如何做到的:

 -(void)drawRect:(CGRect)rect{ CGContextRef context = UIGraphicsGetCurrentContext(); [[UIColor darkGrayColor]setFill]; //this becomes the color of the alpha mask CGContextFillRect(context, rect); CGContextSaveState(context); [[UIColor whiteColor]setFill]; //Have to flip the context since core graphics is done in cartesian coordinates CGContextTranslateCTM(context, 0, rect.size.height); CGContextScaleCTM(context, 1.0, -1.0); [textToDraw drawInRect:rect withFont:[UIFont fontWithName:@"HelveticaNeue-Thin" size:40]; CGContextRestoreGState(context); CGImageRef alphaMask = CGBitmapContextCreateImage(context); [[UIColor whiteColor]setFill]; CGContextFillRect(context, rect); CGContextSaveGState(context); CGContentClipToMask(context, rect, alphaMask); [backgroundImage drawInRect:rect]; CGContextRestoreGState(context); CGImageRelease(alphaMask); } - (void)setTextToDraw:(NSString*)text{ if(text != textToDraw){ textToDraw = text; [self setNeedsDisplay]; } } 

我有一个textToDraw@synthesize声明,所以我可以重写setter并调用[self setNeedsDisplay] 。 不知道这是完全必要的。

我敢肯定,这有一些拼写错误,但我可以向你保证,拼写检查版本运行良好。