IOS 图文混排(CoreText.framework)详解及实例
程序员文章站
2023-12-20 11:25:16
ios 图文混排(coretext.framework)
本文主要介绍了ios图文混排...
ios 图文混排(coretext.framework)
本文主要介绍了ios图文混排的资料,这里整理了在网上查找的内容,帮助理解,掌握这部分知识,以下就是整理的内容:
利用coretext进行图文混排。
实现代码:
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的委托,主要是用于指定对象的上行高,宽,或上下文释放时使用。
-(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];
//换行模式 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); }
效果:
从上面看大家可能没有发现什么问题,当把图片放在字的最左边会是什么样子的?
因此为了避免这种情况发生,我在代码中添加了换行模式。添加换行后的效果:
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!