iOS UIView子类,将透视文本绘制到背景
我想在UIView的子类上绘制文本,这样文本就被剪切掉了,并且视图背后的背景显示出来,就像在这里find的OSX Mavericks标志一样。
我会说,我更像是一个中级/早期的高级iOS开发人员,所以随时可以给我一些疯狂的解决scheme。 我希望我不得不重写drawRect
为了做到这一点。
多谢你们!
编辑:
我应该提到,我的第一个尝试是使文本[UIColor clearColor]
这是行不通的,因为它只是将文本的alpha分量设置为0,它只是显示了文本的视图。
免责声明:我正在写这个没有testing,所以原谅我,如果我在这里错了。
你应该通过以下两个步骤来实现你所需要的:
-
用你的视图的大小创build一个
CATextLayer
,设置backgroundColor
是完全透明的并且foregroundColor
是不透明的[UIColor colorWithWhite:0 alpha:1]
通过[UIColor colorWithWhite:0 alpha:1]
和[UIColor colorWithWhite:0 alpha:0]
。然后设置string
属性为要渲染的string,font
和fontSize
等 -
将视图的图层蒙版设置为这个图层:
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]
。 不知道这是完全必要的。
我敢肯定,这有一些拼写错误,但我可以向你保证,拼写检查版本运行良好。