设置文字和图片的方法:
注释全部写在例子对应的位置上:
- (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); }
Demo 下载地址:https://github.com/caigee/iosdev_sample
下的DemoCoreText
厚吾(http://blog.csdn.net/mangosnow)
本文遵循“署名-非商业用途-保持一致”创作公用协议