MST

星途 面试题库

面试题:Objective-C的Core Text中如何处理复杂的字体样式混合排版

假设在一个Objective-C的应用场景下,有一段文本需要部分文字使用宋体、16号字、加粗,部分文字使用黑体、14号字、斜体,且整体文字颜色有渐变色效果,利用Core Text框架,阐述实现思路并写出核心实现代码。
14.9万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 创建可变属性字符串:使用NSMutableAttributedString来存储文本,并为不同部分的文本设置不同的字体、字号、加粗、斜体等属性。
  2. 设置颜色渐变效果:通过CTGradientRef来创建颜色渐变对象,并将其应用到属性字符串上。
  3. 创建CTFramesetter:利用属性字符串创建CTFramesetter
  4. 绘制文本:根据需要绘制文本的区域,创建CTFrame,并将其绘制到对应的上下文。

核心实现代码

#import <UIKit/UIKit.h>
#import <CoreText/CoreText.h>

@interface ViewController : UIViewController

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 创建文本
    NSString *text = @"部分宋体16号字加粗,部分黑体14号字斜体";
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text];
    
    // 设置宋体、16号字、加粗部分
    UIFont *songFont = [UIFont fontWithName:@"STSong" size:16];
    NSDictionary *songAttributes = @{
        NSFontAttributeName : songFont,
        NSFontWeightAttribute : @(UIFontWeightBold)
    };
    [attributedString setAttributes:songAttributes range:NSMakeRange(0, 9)];
    
    // 设置黑体、14号字、斜体部分
    UIFont *heiFont = [UIFont fontWithName:@"Heiti SC" size:14];
    NSDictionary *heiAttributes = @{
        NSFontAttributeName : heiFont,
        NSObliquenessAttributeName : @(0.2)
    };
    [attributedString setAttributes:heiAttributes range:NSMakeRange(9, text.length - 9)];
    
    // 创建颜色渐变
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGFloat components[] = {1.0, 0.0, 0.0, 1.0,  // 起始颜色:红色
                            0.0, 1.0, 0.0, 1.0}; // 结束颜色:绿色
    CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, NULL, 2);
    CGColorSpaceRelease(colorSpace);
    
    // 将颜色渐变应用到属性字符串
    [attributedString addAttribute:(id)kCTForegroundColorGradientAttributeName value:(__bridge id)gradient range:NSMakeRange(0, text.length)];
    CGGradientRelease(gradient);
    
    // 创建CTFramesetter
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attributedString);
    
    // 设置绘制区域
    CGRect rect = CGRectMake(50, 100, 200, 200);
    CGPathRef path = CGPathCreateWithRect(rect, NULL);
    
    // 创建CTFrame
    CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
    
    // 绘制文本
    UIGraphicsBeginImageContext(self.view.bounds.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    CGContextTranslateCTM(context, 0, self.view.bounds.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CTFrameDraw(frame, context);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    [self.view addSubview:imageView];
    
    CFRelease(frame);
    CFRelease(path);
    CFRelease(framesetter);
}

@end