You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取指定字体下特定字符串的ascent与descent值?

iOS 获取自定义字体下特定字符串的Ascent与Descent值

问题场景

已通过以下代码获取自定义字体的UIFont实例:

UIFont* font = [UIFont fontWithName:@"SourceHanSans-Medium" size:nEmSize];

使用sizeWithAttributes:获取字符串高度时,返回值等于字体尺寸nEmSize,无法满足精确排版需求,因此需要获取特定字符串在该字体下的ascent(基线到字符顶部的距离)和descent(基线到字符底部的距离)。

解决方案

要获取特定字符串的精确排版属性,需借助CoreText框架计算,具体实现如下:

1. 导入CoreText框架

在文件头部添加导入语句:

#import <CoreText/CoreText.h>

2. 编写计算方法

通过CTLine对象获取字符串的排版边界:

- (void)calculateStringAscentAndDescent:(NSString *)targetStr withFont:(UIFont *)font {
    // 构建CoreText属性字典
    NSDictionary *ctAttributes = @{
        (__bridge NSString *)kCTFontAttributeName: font
    };
    
    // 创建带属性的CoreText字符串
    CFAttributedStringRef attrString = CFAttributedStringCreate(
        kCFAllocatorDefault,
        (__bridge CFStringRef)targetStr,
        (__bridge CFDictionaryRef)ctAttributes
    );
    
    // 创建用于排版计算的CTLine对象
    CTLineRef textLine = CTLineCreateWithAttributedString(attrString);
    
    CGFloat ascent, descent, leading;
    // 获取排版层面的ascent、descent和行间距leading
    CTLineGetTypographicBounds(textLine, &ascent, &descent, &leading);
    
    // 输出结果:ascent为基线到字符顶部的正数,descent为基线到字符底部的正数
    NSLog(@"字符串Ascent: %.2f, Descent: %.2f", ascent, descent);
    
    // 释放CoreText对象,避免内存泄漏
    CFRelease(textLine);
    CFRelease(attrString);
}

3. 字体默认属性(可选)

如果仅需获取字体本身的默认ascent和descent(而非特定字符串的),可直接使用UIFont的内置属性:

// 字体默认ascender(基线到顶部的距离,正数)
CGFloat defaultAscent = font.ascender;
// 字体默认descender为负数,取绝对值得到基线到底部的距离
CGFloat defaultDescent = -font.descender;

说明

  • sizeWithAttributes:返回的是字符串的包围盒高度,当字符串字符未超出字体em框时,该值可能等于字体尺寸,但无法反映实际排版的基线偏移信息。
  • CoreText的CTLineGetTypographicBounds返回的是排版层面的精确值,适用于需要精细控制文本布局的场景。

内容的提问来源于stack exchange,提问作者Jungwon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 03:52:49