应用场景:比如有个化学方程式2H2+O2=2H2O,比如要显示2的3次方,2^3.
一、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 字形常见参数
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赋值略有不同。