rob*_*off 90
在iOS 7.0中,Apple NSTextEffectAttributeName
为属性字符串添加了一个新属性.如果部署目标是iOS 7.0或更高版本,则可以将此属性设置为NSTextEffectLetterpressStyle
以浮雕样式绘制属性字符串.
我不能肯定Apple如何绘制浮雕文字.它看起来像是用红色填充字符串字形,然后在字形的内边缘周围应用阴影,并在字形的顶部外边缘应用非常微弱的阴影.我试了一下,这就是它的样子:
最重要的是我的渲染.下面是一个简单的UILabel,带有影子,克里斯在他的回答中提出.我在后台放了一个Reminders应用程序的屏幕截图.
这是我的代码.
首先,您需要一个能够创建字符串图像蒙版的函数.您将使用蒙版来绘制字符串本身,然后绘制仅出现在字符串内边缘周围的阴影.此图像只有一个alpha通道,没有RGB通道.
- (UIImage *)maskWithString:(NSString *)string font:(UIFont *)font size:(CGSize)size
{
CGRect rect = { CGPointZero, size };
CGFloat scale = [UIScreen mainScreen].scale;
CGColorSpaceRef grayscale = CGColorSpaceCreateDeviceGray();
CGContextRef gc = CGBitmapContextCreate(NULL, size.width * scale, size.height * scale, 8, size.width * scale, grayscale, kCGImageAlphaOnly);
CGContextScaleCTM(gc, scale, scale);
CGColorSpaceRelease(grayscale);
UIGraphicsPushContext(gc); {
[[UIColor whiteColor] setFill];
[string drawInRect:rect withFont:font];
} UIGraphicsPopContext();
CGImageRef cgImage = CGBitmapContextCreateImage(gc);
CGContextRelease(gc);
UIImage *image = [UIImage imageWithCGImage:cgImage scale:scale orientation:UIImageOrientationDownMirrored];
CGImageRelease(cgImage);
return image;
}
Run Code Online (Sandbox Code Playgroud)
其次,您需要一个反转该掩码的函数.您将使用它来使CoreGraphics在字符串的内边缘周围绘制阴影.这需要是一个完整的RGBA图像.(iOS似乎不支持灰度+ alpha图像.)
- (UIImage *)invertedMaskWithMask:(UIImage *)mask
{
CGRect rect = { CGPointZero, mask.size };
UIGraphicsBeginImageContextWithOptions(rect.size, NO, mask.scale); {
[[UIColor blackColor] setFill];
UIRectFill(rect);
CGContextClipToMask(UIGraphicsGetCurrentContext(), rect, mask.CGImage);
CGContextClearRect(UIGraphicsGetCurrentContext(), rect);
}
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Run Code Online (Sandbox Code Playgroud)
您可以在函数中使用这些函数,该函数以红色绘制字符串并将阴影应用于其内部边缘.
-(UIImage *)imageWithInteriorShadowAndString:(NSString *)string font:(UIFont *)font textColor:(UIColor *)textColor size:(CGSize)size
{
CGRect rect = { CGPointZero, size };
UIImage *mask = [self maskWithString:string font:font size:rect.size];
UIImage *invertedMask = [self invertedMaskWithMask:mask];
UIImage *image;
UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale); {
CGContextRef gc = UIGraphicsGetCurrentContext();
// Clip to the mask that only allows drawing inside the string's image.
CGContextClipToMask(gc, rect, mask.CGImage);
// We apply the mask twice because we're going to draw through it twice.
// Only applying it once would make the edges too sharp.
CGContextClipToMask(gc, rect, mask.CGImage);
mask = nil; // done with mask; let ARC free it
// Draw the red text.
[textColor setFill];
CGContextFillRect(gc, rect);
// Draw the interior shadow.
CGContextSetShadowWithColor(gc, CGSizeZero, 1.6, [UIColor colorWithWhite:.3 alpha:1].CGColor);
[invertedMask drawAtPoint:CGPointZero];
invertedMask = nil; // done with invertedMask; let ARC free it
image = UIGraphicsGetImageFromCurrentImageContext();
}
UIGraphicsEndImageContext();
return image;
}
Run Code Online (Sandbox Code Playgroud)
接下来,您需要一个获取图像并返回带有微弱向上阴影的副本的函数.
- (UIImage *)imageWithUpwardShadowAndImage:(UIImage *)image
{
UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale); {
CGContextSetShadowWithColor(UIGraphicsGetCurrentContext(), CGSizeMake(0, -1), 1, [UIColor colorWithWhite:0 alpha:.15].CGColor);
[image drawAtPoint:CGPointZero];
}
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resultImage;
}
Run Code Online (Sandbox Code Playgroud)
最后,您可以组合这些功能来创建字符串的浮雕图像.我把我的最终图像放入一个UIImageView
易于测试的地方.
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect rect = self.imageView.bounds;
NSString *string = @"Reminders";
UIFont *font = [UIFont systemFontOfSize:33];
UIImage *interiorShadowImage = [self imageWithInteriorShadowAndString:string
font:font
textColor:[UIColor colorWithHue:0 saturation:.9 brightness:.7 alpha:1]
size:rect.size];
UIImage *finalImage = [self imageWithUpwardShadowAndImage:interiorShadowImage];
self.imageView.image = finalImage;
}
Run Code Online (Sandbox Code Playgroud)
这看起来就像是文本周围的阴影.您在IB中设置文本颜色的相同区域中设置它 - 为阴影选择合适的颜色并设置阴影偏移的方式(在您发布的示例中,看起来它们将阴影颜色设置为相同的颜色作为文本并将其偏移0水平和-1垂直(这意味着一个像素向上).
在代码中,属性设置如下(假设您已经设置了一个名为"标签"的UILabel:
label.shadowColor = [UIColor blackColor]; // Choose your color here - in the example
// posted, they probably chose a similar color
// to the text color and then set the alpha
// down around 0.7 or so so the shadow would be
// faint.
label.shadowOffset = CGSizeMake(0,-1); // First parameter is horizontal, second is vertical
Run Code Online (Sandbox Code Playgroud)