服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - IOS 图文混排(CoreText.framework)详解及实例

IOS 图文混排(CoreText.framework)详解及实例

2021-02-20 15:53边缘998 IOS

这篇文章主要介绍了IOS 图文混排(CoreText.framework)详解及实例的相关资料,这里对IOS 的图文混排进行了详细介绍,并附代码实例,和实现效果图,需要的朋友可以参考下

ios 图文混排(coretext.framework)

       本文主要介绍了ios图文混排的资料,这里整理了在网上查找的内容,帮助理解,掌握这部分知识,以下就是整理的内容:   

利用coretext进行图文混排。

实现代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void rundelegatedealloccallback( void* refcon ){
   
}
 
cgfloat rundelegategetascentcallback( void *refcon ){
  nsstring *imagename = (nsstring *)refcon;
  return 80;//[uiimage imagenamed:imagename].size.height;
}
 
cgfloat rundelegategetdescentcallback(void *refcon){
  return 0;
}
 
cgfloat rundelegategetwidthcallback(void *refcon){
  nsstring *imagename = (nsstring *)refcon;
  return 100;//[uiimage imagenamed:imagename].size.width;
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
-(void)drawcharandpicture
{
  cgcontextref context = uigraphicsgetcurrentcontext();
   
  cgcontextsettextmatrix(context, cgaffinetransformidentity);//设置字形变换矩阵为cgaffinetransformidentity,也就是说每一个字形都不做图形变换
   
  cgaffinetransform flipvertical = cgaffinetransformmake(1,0,0,-1,0,self.bounds.size.height);
  cgcontextconcatctm(context, flipvertical);//将当前context的坐标系进行flip
  nslog(@"bh=%f",self.bounds.size.height);
   
  nsmutableattributedstring *attributedstring = [[[nsmutableattributedstring alloc] initwithstring:@"请在这里插入一张图片位置"] autorelease];
   
   
  //为图片设置ctrundelegate,delegate决定留给图片的空间大小
  nsstring *imgname = @"img.png";
  ctrundelegatecallbacks imagecallbacks;
  imagecallbacks.version = kctrundelegateversion1;
  imagecallbacks.dealloc = rundelegatedealloccallback;
  imagecallbacks.getascent = rundelegategetascentcallback;
  imagecallbacks.getdescent = rundelegategetdescentcallback;
  imagecallbacks.getwidth = rundelegategetwidthcallback;
  ctrundelegateref rundelegate = ctrundelegatecreate(&imagecallbacks, imgname);
  nsmutableattributedstring *imageattributedstring = [[nsmutableattributedstring alloc] initwithstring:@" "];//空格用于给图片留位置
  [imageattributedstring addattribute:(nsstring *)kctrundelegateattributename value:(id)rundelegate range:nsmakerange(0, 1)];
  cfrelease(rundelegate);
   
  [imageattributedstring addattribute:@"imagename" value:imgname range:nsmakerange(0, 1)];
   
  [attributedstring insertattributedstring:imageattributedstring atindex:4];
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//换行模式
  ctparagraphstylesetting linebreakmode;
  ctlinebreakmode linebreak = kctlinebreakbycharwrapping;
  linebreakmode.spec = kctparagraphstylespecifierlinebreakmode;
  linebreakmode.value = &linebreak;
  linebreakmode.valuesize = sizeof(ctlinebreakmode);
   
  ctparagraphstylesetting settings[] = {
    linebreakmode
  };
   
  ctparagraphstyleref style = ctparagraphstylecreate(settings, 1);
   
     
  // build attributes
  nsmutabledictionary *attributes = [nsmutabledictionary dictionarywithobject:(id)style forkey:(id)kctparagraphstyleattributename ];
   
  // set attributes to attributed string
  [attributedstring addattributes:attributes range:nsmakerange(0, [attributedstring length])];
   
 
   
  ctframesetterref ctframesetter = ctframesettercreatewithattributedstring((cfmutableattributedstringref)attributedstring);
   
  cgmutablepathref path = cgpathcreatemutable();
  cgrect bounds = cgrectmake(0.0, 0.0, self.bounds.size.width, self.bounds.size.height);
  cgpathaddrect(path, null, bounds);
   
  ctframeref ctframe = ctframesettercreateframe(ctframesetter,cfrangemake(0, 0), path, null);
  ctframedraw(ctframe, context);
   
  cfarrayref lines = ctframegetlines(ctframe);
  cgpoint lineorigins[cfarraygetcount(lines)];
  ctframegetlineorigins(ctframe, cfrangemake(0, 0), lineorigins);
  nslog(@"line count = %ld",cfarraygetcount(lines));
  for (int i = 0; i < cfarraygetcount(lines); i++) {
    ctlineref line = cfarraygetvalueatindex(lines, i);
    cgfloat lineascent;
    cgfloat linedescent;
    cgfloat lineleading;
    ctlinegettypographicbounds(line, &lineascent, &linedescent, &lineleading);
    nslog(@"ascent = %f,descent = %f,leading = %f",lineascent,linedescent,lineleading);
     
    cfarrayref runs = ctlinegetglyphruns(line);
    nslog(@"run count = %ld",cfarraygetcount(runs));
    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);
      nslog(@"width = %f",runrect.size.width);
       
      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;
          cgcontextdrawimage(context, imagedrawrect, image.cgimage);
        }
      }
    }
  }
   
  cfrelease(ctframe);
  cfrelease(path);
  cfrelease(ctframesetter);
}

效果:

IOS 图文混排(CoreText.framework)详解及实例

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

IOS 图文混排(CoreText.framework)详解及实例

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

IOS 图文混排(CoreText.framework)详解及实例

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

原文链接:http://blog.csdn.net/fengsh998/article/details/8714497

延伸 · 阅读

精彩推荐
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17