【问题标题】:CATextlayer set line spacing?CATextlayer 设置行距?
【发布时间】:2013-07-20 17:34:08
【问题描述】:

我对 CATextlayer 有疑问。我为 CATextlayer 设置了 Wrapped == YES 并为此自动设置了多行。但是行间距很小,看起来很糟糕。 有没有办法为 CATextlayer 设置行距?谢谢。

【问题讨论】:

    标签: iphone ios catextlayer


    【解决方案1】:

    我认为CATextLayer 仅用于轻量级用途。您可以将其 string 属性设置为 NSAttributedString 以更改某些属性,例如字体和大小,但许多其他属性会被忽略,包括行高和间距。

    为了更好地控制图层中文本的呈现方式,您可以使用常规的CALayerNSAttributedString 的绘图方法;例如:

    - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
        [NSGraphicsContext saveGraphicsState];
        [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:ctx flipped:YES]];
        [self.someAttributedString drawInRect:layer.bounds];
        [NSGraphicsContext restoreGraphicsState];
    }
    

    【讨论】:

      【解决方案2】:

      与@spinacher 一样,我注意到CATextLayer 忽略了行距等段落样式。我通过继承 CALayer 并更直接地绘制属性字符串来解决这个问题。大部分代码抄自this article

      class CAAttributedTextLayer: CALayer {
          
          public var attrString = NSAttributedString(string: "")
          
          override func draw(in ctx: CGContext) {
              
              // Flip the coordinate system
              ctx.textMatrix = .identity
              ctx.translateBy(x: 0, y: bounds.size.height)
              ctx.scaleBy(x: 1.0, y: -1.0)
              
              let path = CGMutablePath()
              path.addRect(bounds)
              
              let framesetter = CTFramesetterCreateWithAttributedString(attrString as CFAttributedString)
              let frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attrString.length), path, nil)
              CTFrameDraw(frame, ctx)
          }
      }
      

      【讨论】:

      • 如何使用上面的代码?你能给出任何代码示例吗?
      • @HardikThakkar 只需将类添加到您的代码中,并将您的 CATextLayer 替换为 CAAttributedTextLayer。然后将 attrString 属性设置为属性字符串
      • 好的,谢谢...
      【解决方案3】:

      CATextLayer lineheight 取决于你的字体原生高度1 unit
      通常用名为“Geviert”的印刷单位类型表示。

      如果您能够编辑字体 - 当然您也可以设置行高。因为当 Quartz 解释/渲染你的字体时,使用一个签名的最大单位大小的单位大小。

      抱歉,在德语屏幕截图中,字体编辑设置为只有 6 个像素高度和两个像素的行距。即使在字体创建软件中,读取行高也不是很明显,如您所见。没有任何地方将 2 个像素作为线空间给出.. 而是在此处给出单位大小的 Geviert。

      所以是的,没有其他方法 CATextLayer 可以以本机方式打印其他行高。您将始终必须通过读出 NSString 的 "\n" 并为下一行重新分配另一个 CATextLayer 或与其他类一起在屏幕上打印文本来使用解决方法,例如 torof 中的示例用CAAttributedTextLayer可以表达NSAttributedStrings

      Quartz 渲染的 Lineheight 是一个取决于字体的相对大小。 有些字体需要更多的行空间,因为它们在圆圈和下划线图形中很重。如果此相对行高不存在,则您必须在每个文本打印上指定行高,而不是使用标准 1 unit * Geviert size + size below any sign(屏幕截图“Unterlänge”)

      当您可以编辑字体文件并将提到的Geviert 大小设置为您希望的值时,CATextLayer 将始终以完美的行高呈现。当您为 LCD 或其他低像素显示器创建图像缓冲区时,这非常方便。

      【讨论】:

      • ps:屏幕截图是在 glyphs mini 中制作的。
      【解决方案4】:

      您可以参考以下教程:

      Height-for-width layout with CATextLayer

      【讨论】:

      • 这根本不能回答问题。问题是关于更改CATextLayer 的行距,而不是计算特定宽度的高度...
      猜你喜欢
      • 1970-01-01
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 2011-04-22
      • 1970-01-01
      • 2012-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多