如何获取指定字体下特定字符串的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
相关产品推荐
相关产品推荐

