当前位置: 移动技术网 > IT编程>移动开发>IOS > IOS 图文混排(CoreText.framework)详解及实例

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

2019年07月24日  | 移动技术网IT编程  | 我要评论

职业技能实训,垫底龙妃,浮世绝香结局

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); 
} 

效果:


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


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


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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网