iOS CoreText实现上下角标

作者: 某非著名程序员 | 来源:发表于2019-05-05 18:57 被阅读52次

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


    实现效果

    一、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 字形常见参数


    字形

    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实现上下角标

        本文链接:https://www.haomeiwen.com/subject/jrrinqtx.html