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