【IOS学习】CoreText学习笔记(二)设置文字属性和插入图片

设置文字和图片的方法:

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

注释全部写在例子对应的位置上:


- (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:@"1.设置字形变换矩阵为CGAffineTransformIdentity,也就是说每一个字形都不做图形变换,将当前context的坐标系进行flip,2.为图片设置CTRunDelegate,delegate决定留给图片的空间大小。 3.把图片画上去" ];
    [attributedString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:20] range:NSMakeRange(0, [attributedString length])];
    [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(0.0, 10)];
    [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(10, 20)];
   
    //创建图片位置
    NSString *taobaoImageName = @"meile.png";
    CTRunDelegateCallbacks imageCallbacks;
    imageCallbacks.version = kCTRunDelegateVersion1;
    imageCallbacks.dealloc = RunDelegateDeallocCallback;
    imageCallbacks.getAscent = RunDelegateGetAscentCallback;
    imageCallbacks.getDescent = RunDelegateGetDescentCallback;
    imageCallbacks.getWidth = RunDelegateGetWidthCallback;
   
    CTRunDelegateRef runDelegate = CTRunDelegateCreate(&imageCallbacks, (__bridge void *)taobaoImageName);
    NSMutableAttributedString *imageAttributedString =[[NSMutableAttributedString alloc]initWithString:@" "];//创建一个空格,来使attributedString生效
    [imageAttributedString addAttribute:(NSString *)kCTRunDelegateAttributeName value:(__bridge id)runDelegate range:NSMakeRange(0, 1)];//设置回调
    CFRelease(runDelegate);
   
    [imageAttributedString addAttribute:@"imageName" value:taobaoImageName range:NSMakeRange(0, 1)];
    [attributedString insertAttributedString:imageAttributedString atIndex:30];//把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);
}

参考资料: http://geeklu.com/2013/03/core-text/

Demo 下载地址:https://github.com/caigee/iosdev_sample

下的DemoCoreText

厚吾http://blog.csdn.net/mangosnow

本文遵循“署名-非商业用途-保持一致”创作公用协议



  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值