CoreText 设置文字属性和插入图片

Posted 沈成才

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CoreText 设置文字属性和插入图片相关的知识,希望对你有一定的参考价值。

设置文字和图片的方法:
绘制文字的步骤是:设置NSAttributedString 或NSMutableAttributedString——> 通过attributedString 生成frameSetter ——> 生成CTFrame——>画出来
设置文字属性,重点是在NSMutableAttributedString的生成,对颜色、字体、字距进行设置。
CoreText 中并没有画图片的方法,我们同样的在NSMutableAttributedString中插入一个空字符,然后设置这个空字符占的位置和大小。把整个字符串写完以后。重点在这里:解析生成的NSAttributedString,获取到图片应该画的位置和大小,利用Core Graphics 把图片画到context中。
注释全部写在例子对应的位置上:

#import <UIKit/UIKit.h>

@interface DetailView : UIView

@property (nonatomic, assign) NSInteger begin;/**< 图片开始位置 */
@property (nonatomic, strong) NSString *imageblank;/**< 图片占位符 */
@property (nonatomic, strong) NSString *imagename;/**< 图片名称 */
@property (nonatomic, strong) NSString *detailtext;/**< 文字字符串 */

@end

#import "DetailView.h"
#import <CoreText/CoreText.h>

@implementation DetailView

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect

    CGContextRef contxt = UIGraphicsGetCurrentContext();
    CGContextSetTextMatrix(contxt, CGAffineTransformIdentity);

    CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, self.bounds.size.height);
    CGContextConcatCTM(contxt, flipVertical);


    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]initWithString:self.detailtext];
    [attributedString addAttribute:NSFontAttributeName value:denzaFont(14) range:NSMakeRange(0, [attributedString length])];
    [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithWhite:0.565 alpha:1.000] range:NSMakeRange(0, [attributedString length])];

    //创建图片位置
    NSString *taobaoImageName = self.imagename;

    NSMutableAttributedString *imageAttributedString =[[NSMutableAttributedString alloc]initWithString:self.imageblank];//创建一个空格,来使attributedString生效//@" "

    [imageAttributedString addAttribute:@"imageName" value:taobaoImageName range:NSMakeRange(0, 1)];
    [attributedString insertAttributedString:imageAttributedString atIndex:self.begin];//把attribute 插入到一个特定的位置
    //创建图片位置至此完成那个

    CTFramesetterRef ctFrameSetter = CTFramesetterCreateWithAttributedString((CFMutableAttributedStringRef)attributedString);
    CGMutablePathRef path = CGPathCreateMutable();
    CGRect bounds = CGRectMake(0.0, 20.0, self.bounds.size.width, self.bounds.size.height-20);
    CGPathAddRect(path, NULL, bounds);

    CTFrameRef ctFrame = CTFramesetterCreateFrame(ctFrameSetter, CFRangeMake(0, 0), path, NULL);
    CTFrameDraw(ctFrame, contxt);

    //现在开始画图片
    CFArrayRef lines = CTFrameGetLines(ctFrame);
    CGPoint lineOrigins [CFArrayGetCount(lines)]; //这是一个方法
    CTFrameGetLineOrigins(ctFrame, CFRangeMake(0, 0), lineOrigins);


    for (int i = 0; i < CFArrayGetCount(lines); i++) 
        CTLineRef line = CFArrayGetValueAtIndex(lines, i);
        CGFloat lineAscent;
        CGFloat lineDescent;
        CGFloat lineLeading;
        CTLineGetTypographicBounds(line, &lineAscent, &lineDescent, &lineLeading);

        CFArrayRef runs = CTLineGetGlyphRuns(line);
        for (int j = 0; j < CFArrayGetCount(runs); j++) 
            CGFloat runAscent;
            CGFloat runDescent;
            CGPoint lineOrigin = lineOrigins[i];
            CTRunRef run = CFArrayGetValueAtIndex(runs, j);
            NSDictionary* attributes = (NSDictionary*)CTRunGetAttributes(run);
            CGRect runRect;
            runRect.size.width = CTRunGetTypographicBounds(run, CFRangeMake(0,0), &runAscent, &runDescent, NULL);

            runRect=CGRectMake(lineOrigin.x + CTLineGetOffsetForStringIndex(line, CTRunGetStringRange(run).location, NULL), lineOrigin.y - runDescent, runRect.size.width, runAscent + runDescent);

            NSString *imageName = [attributes objectForKey:@"imageName"];
            //图片渲染逻辑
            if (imageName)
            
                UIImage *image = [UIImage imageNamed:imageName];
                if (image)
                
                    CGRect imageDrawRect;
                    imageDrawRect.size = image.size;
                    imageDrawRect.origin.x = runRect.origin.x + lineOrigin.x;
                    imageDrawRect.origin.y = lineOrigin.y +lineDescent+10;// 怎么精确计算
                    CGContextDrawImage(contxt, imageDrawRect, image.CGImage);
                
            
        
    

    //画图片结束

    CFRelease(ctFrame);
    CFRelease(path);
    CFRelease(ctFrameSetter);


@end

以上是关于CoreText 设置文字属性和插入图片的主要内容,如果未能解决你的问题,请参考以下文章

iOS 富文本编辑器(插入图片,设置字体)

CoreText

页眉插入图片,文字和页号(码)的设置

python,让文字变成图片

怎么设置整个html的背景颜色

图片img