vertically align text in a CATextLayer?

William Jockusch picture William Jockusch · Jan 22, 2011 · Viewed 17.2k times · Source

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 want to center it vertically -- but information about other vertical alignments would also be of interest.

EDIT: I found this, but I can't make it work.

Answer

iamktothed picture iamktothed · Sep 8, 2015

The correct answer, as you've already found, is here in Objective-C and works for iOS. It works by subclassing the CATextLayer and overriding the drawInContext function.

However, I've made some improvements to the code, as shown below, using David Hoerl's code as a basis. The changes come solely in recalculating the vertical position of the text represented by the yDiff. I've tested it with my own code.

Here is the code for Swift users:

class LCTextLayer : CATextLayer {

    // REF: http://lists.apple.com/archives/quartz-dev/2008/Aug/msg00016.html
    // CREDIT: David Hoerl - https://github.com/dhoerl 
    // USAGE: To fix the vertical alignment issue that currently exists within the CATextLayer class. Change made to the yDiff calculation.

    override func draw(in context: CGContext) {
        let height = self.bounds.size.height
        let fontSize = self.fontSize
        let yDiff = (height-fontSize)/2 - fontSize/10

        context.saveGState()
        context.translateBy(x: 0, y: yDiff) // Use -yDiff when in non-flipped coordinates (like macOS's default)
        super.draw(in: context)
        context.restoreGState()
    }
}