iOS CoreText实现上下角标

应用场景:比如有个化学方程式2H2+O2=2H2O,比如要显示2的3次方,2^3.


iOS CoreText实现上下角标_第1张图片
实现效果

一、CoreText基本使用

请挪步至:iOS实现仿真翻页及CoreText文字图片排版

二、CTRun的使用

CTFrameRef粒度较大,处理单行单个属性时使用CTRun最合适。

2.1CTFrameRef转CTLineRef

CFArrayRef Lines = CTFrameGetLines(frameRef);//获取frame中CTLineRef数组
CFIndex lineCount = CFArrayGetCount(Lines);//获取数组Lines中的个数
CTLineRef lineRef = CFArrayGetValueAtIndex(Lines, i);//获取单行CTLineRef

2.2 CTLineRef转CTRun

CFArrayRef runs = CTLineGetGlyphRuns(_lineRef);//获取lineRef中CTRunRef数组
CFIndex runCount = CFArrayGetCount(runs);//获取数组runs中的个数

2.3 CTRun绘制

CGContextSetTextPosition(context, textPosition.x, textPosition.y);//设置CTRun的位置
CTRunDraw(_runRef, context, CFRangeMake(0, 0));//绘制CTRun

三、右下标实现

3.1实现原理

获取sub标签,把对应字符的y设置为Baseline,height设置为Decent,角标的字体是正常的2/3。

贴一张Glyphs 字形常见参数


iOS CoreText实现上下角标_第2张图片
字形

3.2height设置为Decent

高度设置是在解析中设置的。

追加字符后,设置CTRun的高度
NSRange badgeRange = NSMakeRange(contentRange.location, contentRange.length);
[attr addAttribute:NSBaselineOffsetAttributeName value:@(baselineOffset) range:badgeRange];
设置对应属性
CFAttributedStringSetAttributes(_contentAttributed, contentRange, dictionary, NO);

3.3y设置为Baseline

考虑到CTFrame粒度太大,采用更小的粒度CTRun。

CTRunDraw是绘制CTRun的方法,需要设置CGPoint
CGFloat y = [oneRun frameOfGlyphAtIndex:0].origin.y;
CGPoint textPosition = CGPointMake(oneLine.lineFrame.origin.x, configManager.height - y - oneRun.ascent);
CGContextSetTextPosition(context, textPosition.x, textPosition.y);

3.4角标的字体是正常的2/3

UIFont *badgeFont = [UIFont fontWithName:fontFamily size:fontSize * 2 / 3];
UIFont *textFont = [UIFont fontWithName:fontFamily size:fontSize];

3.5右上角角标实现

同sub类似,y和height赋值略有不同。

总结:具体实现上,细节还需要打磨。最后附上demo.

你可能感兴趣的:(iOS CoreText实现上下角标)