美文网首页iOS-阅读器系列
CoreText的认识(二)

CoreText的认识(二)

作者: 向日葵的夏天_summer | 来源:发表于2018-12-18 10:29 被阅读0次

1.创建CTRunDelegate

  • 创建CTRunDelegate对象,并且传递callback和参数

      var imageName = "e_banner"
      var imageCallBack = CTRunDelegateCallbacks(version: kCTRunDelegateVersion1, dealloc: { (_) in
          print("-------")
      }, getAscent: { (ascent) -> CGFloat in
          return 80
      }, getDescent: { (descent) -> CGFloat in
          return 0
      }) { (width) -> CGFloat in
          return 200
      }
      let runDelegate = CTRunDelegateCreate(&imageCallBack, &imageName)
    
  • 创建一个富文本类型的图片占位图,绑定代理

      let imageString = NSMutableAttributedString(string: " ")
      imageString.addAttribute(NSAttributedString.Key(rawValue: kCTRunDelegateAttributeName as String), value: runDelegate!, range: NSRange(location: 0, length: 1))
      imageString.addAttribute(NSAttributedString.Key.init(rawValue: "imageName"), value: imageName, range: NSRange(location: 0, length: 1))
    
  • 将图片占位符插入到我们的富文本中

      attString.insert(imageString, at: 14)
    

2.通过遍历CTLine中的CTRun计算图片所在位置

  • 首先遍历CTLine

  • 遍历每个Line下的CTRun

  • 拿到每个CTRun的attribute属性,并判断代理是否为空,文字的代理为空,而图片代理是不为空的;

  • 计算CTRun的frame

  • 通过CTLine获取对应的原点,CTRunGetTypographicBounds获取宽和ascent,descent;

      // 处理绘制图片的逻辑
      let lines = CTFrameGetLines(frame) as Array
      var originsArrays = [CGPoint](repeating: CGPoint.zero, count: lines.count)
      let range = CFRangeMake(0, 0)
      CTFrameGetLineOrigins(frame, range, &originsArrays)
      for i in 0..<lines.count {
          let line = lines[i]
    
          let runs = CTLineGetGlyphRuns(line as! CTLine) as Array
    
          for j in 0..<runs.count {
              
              let run = runs[j]
              
              let attributes = CTRunGetAttributes(run as! CTRun) as NSDictionary
              
              if attributes.value(forKey: kCTRunDelegateAttributeName as String) == nil {
                  continue
              }
      
              if let imageUrlStr = attributes["imageName"] as? String, let image = UIImage(named: imageUrlStr) {
                  
                  var runAscent = CGFloat()
                  var runDescent = CGFloat()
                  let lineOrigin = originsArrays[i]
                  
                  let width = CTRunGetTypographicBounds(run as! CTRun, CFRangeMake(0, 0), &runAscent, &runDescent, nil)
                  
                  let runRect = CGRect(x: lineOrigin.x + CTLineGetOffsetForStringIndex(line as! CTLine, CTRunGetStringRange(run as! CTRun).location, nil), y: lineOrigin.y - runDescent, width: CGFloat(width), height: runAscent + runDescent)
                  
                  imageFrame = runRect
                  
                  context?.draw(image.cgImage!, in: runRect)
              }
          }
      }
    

相关文章

  • CoreText的认识(二)

    1.创建CTRunDelegate 创建CTRunDelegate对象,并且传递callback和参数 var ...

  • CoreText的认识(一)

    整理下最近关于学习CoreText的认识和理解 1.关于坐标系 CoreText坐标系和UIKit坐标系是不一样的...

  • CoreText的认识(三)

    1.CoreText的图片点击 2.CoreText的文字点击 遍历CTLine,获取每一个CTLine的fram...

  • YYText

    1.YYKit之YYText2.CoreText实现图文混排和点击事件3.认识 TextKit4.CoreText...

  • CoreText的简单使用(三)

    基于前面文章 《CoreText的简单使用(二)》 的介绍,我们基于CoreText封装了一个简单的文本排版框架,...

  • CoreText

    目录 1.CoreText框架概述 一、CoreText框架概述 1.CoreText框架图 2.Coretext...

  • UILabel获取每行的文本,英文略有误差

    需要使用 #import

  • 基于CoreText的基础排版引擎

    ``` #import“CoreText/CoreText.h" -(void)drawRect:(CGRect)...

  • iOS CoreText(二)

    这篇主要讲利用coreText来实现图文混排和点击事件 图文混排思路 文字的绘制只需要知道文字的大小就够了,而图片...

  • CoreText概述

    CoreText概述 CoreText在文本布局和处理字体过程是很高效的,因为CoreText能直接使用CoreG...

网友评论

    本文标题:CoreText的认识(二)

    本文链接:https://www.haomeiwen.com/subject/aoekkqtx.html