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); } |
效果:
从上面看大家可能没有发现什么问题,当把图片放在字的最左边会是什么样子的?
因此为了避免这种情况发生,我在代码中添加了换行模式。添加换行后的效果:
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
原文链接:http://blog.csdn.net/fengsh998/article/details/8714497