iOS UIView subclass, dibuja text transparente a background

Quiero dibujar text en mi subclass en UIView para que el text se corte de la forma y el background detrás de la vista se vea, al igual que en el logotipo de OSX Mavericks que se encuentra aquí .

Diría que soy más un desarrollador de iOS intermedio / temprano avanzado, así que siéntete libre de lanzarme algunas soluciones locas. Espero tener que anular drawRect para poder hacer esto.

¡Gracias chicos!

EDITAR:

Debo mencionar que mi primer bash fue hacer que el text [UIColor clearColor] no funcionara ya que simplemente configuraba el componente alfa del text en 0, que simplemente mostraba la vista a través del text.

Descargo de responsabilidad: estoy escribiendo esto sin testings, así que perdóname si me equivoco aquí.

Deberías lograr lo que necesitas con estos dos pasos:

  1. Cree un CATextLayer con el tamaño de su vista, configure el color de backgroundColor para que sea completamente transparente y el color de foregroundColor sea ​​opaco (por [UIColor colorWithWhite:0 alpha:1] y [UIColor colorWithWhite:0 alpha:0] . Configure la propiedad string a la cadena que desea representar, font y fontSize etc.

  2. Establezca la máscara de la capa de su vista en esta capa: myView.layer.mask = textLayer . Tendrás que importar QuartzCore para acceder al CALayer de tu vista.

Tenga en count que es posible que haya cambiado entre el color opaco y transparente en el primer paso.

Edit: De hecho, Noah tenía razón. Para superar esto, utilicé CoreGraphics con el modo de fusión kCGBlendModeDestinationOut .

Primero, una vista de muestra que muestra que realmente funciona:

 @implementation TestView - (id)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { self.backgroundColor = [UIColor clearColor]; } return self; } - (void)drawRect:(CGRect)rect { [[UIColor networkingColor] 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 

Después de agregar esto a su controller de vista, verá la vista detrás de TestView Hello! dónde está Hello! es dibujado.

¿Por qué funciona esto?

El modo de fusión se define como R = D*(1 - Sa) , lo que significa que necesitamos valores alfa opuestos que en la capa de mask que sugerí anteriormente. Por lo tanto, todo lo que necesita hacer es dibujar con un color opaco y esto se restará de las cosas que ha dibujado en la vista de antemano.

De hecho, me di count de cómo hacerlo por mi count, pero la respuesta @ StatusReport es completamente válida y funciona como está ahora.

Así es como lo hice:

 -(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]; } } 

Tengo una statement @synthesize para textToDraw para poder anular el configurador y llamar [self setNeedsDisplay] . No estoy seguro si eso es totalmente necesario o no.

Estoy seguro de que esto tiene algunos errores tipocharts, pero puedo asegurarte que la versión correctora funciona perfectamente.