iOS图文混编

图文混编例一:


转自-边缘998


利用CORETEXT进行图文混排。

实现代码:

[cpp]  view plain copy
  1. void RunDelegateDeallocCallback( void* refCon ){  
  2.       
  3. }  
  4.   
  5. CGFloat RunDelegateGetAscentCallback( void *refCon ){  
  6.     NSString *imageName = (NSString *)refCon;  
  7.     return 80;//[UIImage imageNamed:imageName].size.height;  
  8. }  
  9.   
  10. CGFloat RunDelegateGetDescentCallback(void *refCon){  
  11.     return 0;  
  12. }  
  13.   
  14. CGFloat RunDelegateGetWidthCallback(void *refCon){  
  15.     NSString *imageName = (NSString *)refCon;  
  16.     return 100;//[UIImage imageNamed:imageName].size.width;  
  17. }  

先设置一个CTRun的委托,主要是用于指定对象的上行高,宽,或上下文释放时使用。

[cpp]  view plain copy
  1. -(void)drawCharAndPicture  
  2. {  
  3.     CGContextRef context = UIGraphicsGetCurrentContext();  
  4.       
  5.     CGContextSetTextMatrix(context, CGAffineTransformIdentity);//设置字形变换矩阵为CGAffineTransformIdentity,也就是说每一个字形都不做图形变换  
  6.       
  7.     CGAffineTransform flipVertical = CGAffineTransformMake(1,0,0,-1,0,self.bounds.size.height);  
  8.     CGContextConcatCTM(context, flipVertical);//将当前context的坐标系进行flip  
  9.     NSLog(@"bh=%f",self.bounds.size.height);  
  10.       
  11.     NSMutableAttributedString *attributedString = [[[NSMutableAttributedString alloc] initWithString:@"请在这里插入一张图片位置"] autorelease];  
  12.       
  13.       
  14.     //为图片设置CTRunDelegate,delegate决定留给图片的空间大小  
  15.     NSString *imgName = @"img.png";  
  16.     CTRunDelegateCallbacks imageCallbacks;  
  17.     imageCallbacks.version = kCTRunDelegateVersion1;  
  18.     imageCallbacks.dealloc = RunDelegateDeallocCallback;  
  19.     imageCallbacks.getAscent = RunDelegateGetAscentCallback;  
  20.     imageCallbacks.getDescent = RunDelegateGetDescentCallback;  
  21.     imageCallbacks.getWidth = RunDelegateGetWidthCallback;  
  22.     CTRunDelegateRef runDelegate = CTRunDelegateCreate(&imageCallbacks, imgName);  
  23.     NSMutableAttributedString *imageAttributedString = [[NSMutableAttributedString alloc] initWithString:@" "];//空格用于给图片留位置  
  24.     [imageAttributedString addAttribute:(NSString *)kCTRunDelegateAttributeName value:(id)runDelegate range:NSMakeRange(0, 1)];  
  25.     CFRelease(runDelegate);  
  26.       
  27.     [imageAttributedString addAttribute:@"imageName" value:imgName range:NSMakeRange(0, 1)];  
  28.       
  29.     [attributedString insertAttributedString:imageAttributedString atIndex:4];  
  30.       
[cpp]  view plain copy
  1.     //换行模式  
  2.     CTParagraphStyleSetting lineBreakMode;  
  3.     CTLineBreakMode lineBreak = kCTLineBreakByCharWrapping;  
  4.     lineBreakMode.spec = kCTParagraphStyleSpecifierLineBreakMode;  
  5.     lineBreakMode.value = &lineBreak;  
  6.     lineBreakMode.valueSize = sizeof(CTLineBreakMode);  
  7.       
  8.     CTParagraphStyleSetting settings[] = {  
  9.         lineBreakMode  
  10.     };  
  11.       
  12.     CTParagraphStyleRef style = CTParagraphStyleCreate(settings, 1);  
  13.       
  14.           
  15.     // build attributes  
  16.     NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithObject:(id)style forKey:(id)kCTParagraphStyleAttributeName ];  
  17.       
  18.     // set attributes to attributed string  
  19.     [attributedString addAttributes:attributes range:NSMakeRange(0, [attributedString length])];  
  20.       
  21.   
  22.       
  23.     CTFramesetterRef ctFramesetter = CTFramesetterCreateWithAttributedString((CFMutableAttributedStringRef)attributedString);  
  24.       
  25.     CGMutablePathRef path = CGPathCreateMutable();  
  26.     CGRect bounds = CGRectMake(0.0, 0.0, self.bounds.size.width, self.bounds.size.height);  
  27.     CGPathAddRect(path, NULL, bounds);  
  28.       
  29.     CTFrameRef ctFrame = CTFramesetterCreateFrame(ctFramesetter,CFRangeMake(0, 0), path, NULL);  
  30.     CTFrameDraw(ctFrame, context);  
  31.       
  32.     CFArrayRef lines = CTFrameGetLines(ctFrame);  
  33.     CGPoint lineOrigins[CFArrayGetCount(lines)];  
  34.     CTFrameGetLineOrigins(ctFrame, CFRangeMake(0, 0), lineOrigins);  
  35.     NSLog(@"line count = %ld",CFArrayGetCount(lines));  
  36.     for (int i = 0; i < CFArrayGetCount(lines); i++) {  
  37.         CTLineRef line = CFArrayGetValueAtIndex(lines, i);  
  38.         CGFloat lineAscent;  
  39.         CGFloat lineDescent;  
  40.         CGFloat lineLeading;  
  41.         CTLineGetTypographicBounds(line, &lineAscent, &lineDescent, &lineLeading);  
  42.         NSLog(@"ascent = %f,descent = %f,leading = %f",lineAscent,lineDescent,lineLeading);  
  43.           
  44.         CFArrayRef runs = CTLineGetGlyphRuns(line);  
  45.         NSLog(@"run count = %ld",CFArrayGetCount(runs));  
  46.         for (int j = 0; j < CFArrayGetCount(runs); j++) {  
  47.             CGFloat runAscent;  
  48.             CGFloat runDescent;  
  49.             CGPoint lineOrigin = lineOrigins[i];  
  50.             CTRunRef run = CFArrayGetValueAtIndex(runs, j);  
  51.             NSDictionary* attributes = (NSDictionary*)CTRunGetAttributes(run);  
  52.             CGRect runRect;  
  53.             runRect.size.width = CTRunGetTypographicBounds(run, CFRangeMake(0,0), &runAscent, &runDescent, NULL);  
  54.             NSLog(@"width = %f",runRect.size.width);  
  55.               
  56.             runRect=CGRectMake(lineOrigin.x + CTLineGetOffsetForStringIndex(line, CTRunGetStringRange(run).location, NULL), lineOrigin.y - runDescent, runRect.size.width, runAscent + runDescent);  
  57.               
  58.             NSString *imageName = [attributes objectForKey:@"imageName"];  
  59.             //图片渲染逻辑  
  60.             if (imageName) {  
  61.                 UIImage *image = [UIImage imageNamed:imageName];  
  62.                 if (image) {  
  63.                     CGRect imageDrawRect;  
  64.                     imageDrawRect.size = image.size;  
  65.                     imageDrawRect.origin.x = runRect.origin.x + lineOrigin.x;  
  66.                     imageDrawRect.origin.y = lineOrigin.y;  
  67.                     CGContextDrawImage(context, imageDrawRect, image.CGImage);  
  68.                 }  
  69.             }  
  70.         }  
  71.     }  
  72.       
  73.     CFRelease(ctFrame);  
  74.     CFRelease(path);  
  75.     CFRelease(ctFramesetter);  
  76. }  

效果:



从上面看大家可能没有发现什么问题,当把图片放在字的最左边会是什么样子的?


因此为了避免这种情况发生,我在代码中添加了换行模式。添加换行后的效果:



图文混编 例二:

本文转自-红黑联盟

在很多新闻类或有文字展示的应用中现在都会出现图文混排的界面例如网易新闻等,乍一看去相似一个网页,其实这样效果并非由UIWebView 加载网页实现。现在分享一种比较简单的实现方式

 

iOS sdk中为我们提供了一套完善的文字排版开发组件:CoreText。CoreText库中提供了很多的工具来对文本进行操作,例如CTFont、CTLine、CTFrame等。利用这些工具可以对文字字体每一行每一段落进行操作。

此例中默认图片都在右上方,且为了美观和开发简便设定所占宽度都相同。

 

1.         首先,需要引入CoreText库

 

在需要使用的类文件中添加#import <CoreText/CoreText.h>头文件。

2.         设置文本的参数

创建一个NSMutableAttributedString对象,包含所需展示的文本字符串。这样就可以对其进行设置了。通过CTFontCreateWithName函数创建一个CTFont对象,利用NSMutableAttributedString对象的addAttribute方法进行设置。类似的方法可以设置字间距。

对其方式与行间距的设置方式:

[cpp] 
// 文本对齐方式 
    CTTextAlignment alignment = kCTLeftTextAlignment; 
    CTParagraphStyleSetting alignmentStyle; 
    alignmentStyle.spec = kCTParagraphStyleSpecifierAlignment; 
    alignmentStyle.valueSize = sizeof(alignment); 
    alignmentStyle.value = &alignment; 
 // 创建设置数组 
            CTParagraphStyleSetting settings[] ={alignmentStyle}; 
CTParagraphStyleRef style = CTParagraphStyleCreate(settings, 1); 

同样使用addAttribute设置字符串对象。这样的方法还可以设置行间距,段间距等参数。

3.         计算图片所占高度。图片可以使用UIImageView 来进行显示。很容易便可获取每张图片所占总高度。

4.         由于图片宽度是固定的这样就可以计算每行文字缩短的字数。只要文本的总体高度低于图像总高度则文字长度都是缩短的。用CTTypesetterSuggestLineBreak函数动态的计算每一行里的字数,因为每一行里面的中文字、标点符号、数字、字母都不一样所以可以显示的字数肯定也是不同的,所以需要作这样的计算。这样循环直至文本结束,就可以知道有多少行字了。再根据字体高度和行间距得出总的文本高度,如果文本高度大于图片总高度那么显示区域的Frame高度就是文本的高度,反之亦然。

5.         绘制文本:

设置每一行绘制文本的区间:

[cpp]
CFRange lineRange = CFRangeMake(currentIndex, lineLength); 
建立文本行对象 
CTLineRef line = CTTypesetterCreateLine(typeSetter, lineRange); 
CGFloat x = [self textOffsetForLine:line inRect:self.bounds]; 
// 设置一行的位置 
CGContextSetTextPosition(context, x, y); 
// 绘制一行文字 
    CTLineDraw(line, context); 

6.         其他功能:

在完成文本绘制功能后可以加入调整文字大小的功能,和图片的放大的功能。

文字大小可以通过直接设置字体大小后重新绘制文本来实现。

图片放大可以在视图上添加一个新的UIImageView 来展示放大后的图片,并且加入动画效


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值