vertically align text in a CATextLayer?

后端 未结 15 1374
时光说笑
时光说笑 2020-12-10 10:41

I am working on a CATextLayer that I want to use in both Mac and iOS. Can I control the vertical alignment of the text within the layer?

In this particular case, I

15条回答
  •  死守一世寂寞
    2020-12-10 11:10

    I slightly modified this answer by @iamkothed. The differences are:

    • text height calculation is based on NSString.size(with: Attributes). I don't know if it's an improvement over (height-fontSize)/2 - fontSize/10, but I like to think that it is. Although, in my experience, NSString.size(with: Attributes) doesn't always return the most appropriate size.
    • added invertedYAxis property. It was useful for my purposes of exporting this CATextLayer subclass using AVVideoCompositionCoreAnimationTool. AVFoundation operates in "normal" y axis, and that's why I had to add this property.
    • Works only with NSString. You can use Swift's String class though, because it automatically casts to NSString.
    • It ignores CATextLayer.fontSize property and completely relies on CATextLayer.font property which MUST be a UIFont instance.

      class VerticallyCenteredTextLayer: CATextLayer {
          var invertedYAxis: Bool = true
      
          override func draw(in ctx: CGContext) {
              guard let text = string as? NSString, let font = self.font as? UIFont else {
                  super.draw(in: ctx)
                  return
              }
      
              let attributes = [NSAttributedString.Key.font: font]
              let textSize = text.size(withAttributes: attributes)
              var yDiff = (bounds.height - textSize.height) / 2
              if !invertedYAxis {
                  yDiff = -yDiff
              }
              ctx.saveGState()
              ctx.translateBy(x: 0.0, y: yDiff)
              super.draw(in: ctx)
              ctx.restoreGState()
          }
      }
      

提交回复
热议问题