需求:在 UIKit 中為動態文本渲染 3D 立體效果(如倒影、倒角、陰光),類似海報標題風格,不可使用靜態圖片。
UIImage 供 UIImageView 顯示。.h
@interface UIImage (ThreeDEffect)
+ (UIImage *)create3DImageWithText:(NSString *)text
font:(UIFont *)font
foregroundColor:(UIColor *)fgColor
shadowColor:(UIColor *)shadowColor
outlineColor:(UIColor *)outlineColor
depth:(NSInteger)depth;
@end
.m 關鍵邏輯
+ (UIImage *)create3DImageWithText:(NSString *)text font:(UIFont *)font
foregroundColor:(UIColor *)fgColor shadowColor:(UIColor *)shadowColor
outlineColor:(UIColor *)outlineColor depth:(NSInteger)depth {
CGSize textSize = [text sizeWithAttributes:@{NSFontAttributeName: font}];
CGSize imgSize = CGSizeMake(textSize.width + depth + 5, textSize.height + depth + 5);
UIGraphicsBeginImageContextWithOptions(imgSize, NO, [UIScreen mainScreen].scale);
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 生成深度顏色漸變數組(由深到淺)
NSMutableArray *colors = [NSMutableArray array];
[colors addObject:fgColor];
CGFloat *components = (CGFloat *)CGColorGetComponents(fgColor.CGColor);
CGFloat step = 100.0 / depth / 255.0;
for (int i = 0; i < depth; i++) {
for (int k = 0; k < 3; k++)
components[k] = MAX(components[k] - step, 0);
[colors insertObject:[UIColor colorWithRed:components[0] green:components[1] blue:components[2] alpha:components[3]] atIndex:0];
}
// 從底層向頂層繪製
for (int i = 0; i < depth; i++) {
UIColor *layerColor = colors[i];
CGContextSaveGState(ctx);
CGContextSetShouldAntialias(ctx, YES);
// 底層加陰影
if (i == 0)
CGContextSetShadowWithColor(ctx, CGSizeMake(-2, -2), 4, shadowColor.CGColor);
// 中間層加發光
else if (i != depth - 1)
CGContextSetShadowWithColor(ctx, CGSizeMake(-1, -1), 3, layerColor.CGColor);
// 頂層加描邊
if (i == depth - 1) {
CGContextSetLineWidth(ctx, 1);
CGContextSetLineJoin(ctx, kCGLineJoinRound);
CGContextSetTextDrawingMode(ctx, kCGTextStroke);
[outlineColor set];
[text drawAtPoint:CGPointMake(i, i) withAttributes:@{NSFontAttributeName: font}];
}
// 填充
CGContextSetTextDrawingMode(ctx, kCGTextFill);
[layerColor set];
[text drawAtPoint:CGPointMake(i, i) withAttributes:@{NSFontAttributeName: font}];
CGContextRestoreGState(ctx);
}
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
UIImage *img = [UIImage create3DImageWithText:@"3"
font:[UIFont systemFontOfSize:250]
foregroundColor:[UIColor colorWithWhite:0.78 alpha:1]
shadowColor:[UIColor blackColor]
outlineColor:[UIColor colorWithWhite:0.88 alpha:1]
depth:8];
imageView.image = img;
depth 或使用 CALayer 3D 變換(iOS 8+)替代。CATextLayer + transform3D 硬件加速。純 Core Graphics 實現零依賴 3D 文本,靈活適配動態內容。