Вот метод, похожий на метод Мэтта Галлахера, который генерирует инвертированную текстовую маску с изображением.
Выделите (изменяемый) буфер данных. Создайте растровый контекст с 8-битным альфа-каналом. Настройте параметры для рисования текста. Заполните весь буфер в режиме копирования (цвет по умолчанию предполагается, что альфа-значение равно 1). Напишите текст в чистом режиме (альфа-значение 0). Создайте изображение из растрового контекста. Используйте растровое изображение в качестве маски для создания нового изображения из исходного изображения. Создайте новый UIImage и очистите.
Каждый раз, когда значения textString или sourceImage или size меняются, пересоздайте окончательное изображение.
CGSize size = /* assume this exists */;
UIImage *sourceImage = /* assume this exists */;
NSString *textString = /* assume this exists */;
char *text = [textString cStringUsingEncoding:NSMacOSRomanStringEncoding];
NSUInteger len = [textString lengthOfBytesUsingEncoding:cStringUsingEncoding:NSMacOSRomanStringEncoding];
NSMutableData *data = [NSMutableData dataWithLength:size.width*size.height*1];
CGContextRef context = CGBitmapContextCreate([data mutableBytes], size.width, size.height, 8, size.width, NULL, kCGImageAlphaOnly);
CGContextSelectFont(context, "Gill Sans Bold", 64.0f, kCGEncodingMacRoman);
CGContextSetTextDrawingMode(context, kCGTextFill);
CGContextSetBlendMode(context, kCGBlendModeCopy);
CGContextFillRect(context, overlay.bounds);
CGContextSetBlendMode(context, kCGBlendModeClear);
CGContextShowTextAtPoint(context, 16.0f, 16.0f, text, len);
CGImageRef textImage = CGBitmapContextCreateImage(context);
CGImageRef newImage = CGImageCreateWithMask(sourceImage.CGImage, textImage);
UIImage *finalImage = [UIImage imageWithCGImage:newImage];
CGContextRelease(context);
CFRelease(newImage);
CFRelease(textImage);
Другой способ сделать это - поместить textImage в новый слой и установить этот слой на слой вашего представления. (Удалите строки, которые создают «newImage» и «finalImage».) Предполагая, что это происходит где-то внутри кода вашего представления:
CALayer *maskLayer = [[CALayer alloc] init];
CGPoint position = CGPointZero;
// layout the new layer
position = overlay.layer.position;
position.y *= 0.5f;
maskLayer.bounds = overlay.layer.bounds;
maskLayer.position = position;
maskLayer.contents = (__bridge id)textImage;
self.layer.mask = maskLayer;
Есть больше альтернатив, некоторые могут быть лучше (подкласс UIImage и рисовать текст непосредственно в чистом режиме после того, как суперкласс завершил рисование?).