iOS UIView subclass, draw see-through text to background
Disclaimer: I'm writing this without testing, so forgive me if I'm wrong here.
You should achieve what you need by these two steps:
Create a
CATextLayer
with the size of your view, set thebackgroundColor
to be fully transparent andforegroundColor
to be opaque (by[UIColor colorWithWhite:0 alpha:1]
and[UIColor colorWithWhite:0 alpha:0]
. Then set thestring
property to the string you want to render,font
andfontSize
etc.Set your view's layer's mask to this layer:
myView.layer.mask = textLayer
. You'll have to importQuartzCore
to access theCALayer
of your view.
Note that it's possible that I switched between the opaque and transparent color in the first step.
Edit: Indeed, Noah was right. To overcome this, I used CoreGraphics with the kCGBlendModeDestinationOut
blend mode.
First, a sample view that shows that it indeed works:
@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
After adding this to your view controller, you'll see the view behind TestView
where Hello!
is drawn.
Why does this work:
The blend mode is defined as R = D*(1 - Sa)
, meaning we need opposite alpha values than in the mask
layer I suggested earlier. Therefore, all you need to do is to draw with an opaque color and this will be subtracted from the stuff you've drawn on the view beforehand.
If all you want is a white view with some stuff (text images, etc) cut out, then you can just do
yourView.layer.compositingFilter = "screenBlendMode"
This will leave the white parts white and the black parts will be see-through.