I am trying to draw a string in the overriden draw
method of CALayer
(I'm programming for iOS).
override func draw(in ctx: CGContext) {
let font = UIFont.systemFont(ofSize: 30)
let string = NSAttributedString(string: "23", attributes: [NSAttributedStringKey.font: font])
string.draw(at: CGPoint(x: 200, y: 200))
}
This is however not drawing anything (at least nothing is visible). Changing fill and stroke color does not make a difference.
If I draw a line it will show, so the function is being called. I know there is a CATextLayer
but I need to draw the string directly. How are you supposed to draw a string in CGContext
in the Swift 4 era? No amount of net searching has yielded an answer.
I assume you know all other settings. The key here is you have not make the CGContext as current one. Just add two lines code to solve the problem. Hope you get the answer.
override func draw(in ctx: CGContext) {
UIGraphicsPushContext(ctx)
let font = UIFont.systemFont(ofSize: 30)
let string = NSAttributedString(string: "23", attributes: [NSAttributedString.Key.font: font])
string.draw(at: CGPoint(x: 200, y: 200))
UIGraphicsPopContext()
}
The above answer works if a view is focused.
Unfortunately, it won't work in an offscreen Bitmap or CALayer context.
The right and universal way to draw a string in any CGContext is to use the CoreText api. It will work on all Apple platforms, and has a lot of power under the hood.
https://developer.apple.com/documentation/coretext
Example:
import Foundation
import Quartz
/// LazyFoxLayer
///
/// Will draw the "The lazy fox…" string in the bottom right corner of the layer,
/// with a margin of 10 pixels.
class LazyFoxLayer: CALayer {
func draw(ctx: CGContext) {
ctx.saveGState()
// Parameters
let margin: CGFloat = 10
let color = CGColor.black
let fontSize: CGFloat = 32
// You can use the Font Book app to find the name
let fontName = "Chalkboard" as CFString
let font = CTFontCreateWithName(fontName, fontSize, nil)
let attributes: [NSAttributedString.Key : Any] = [.font: font, .foregroundColor: color]
// Text
let string = "The lazy fox…"
let attributedString = NSAttributedString(string: string,
attributes: attributes)
// Render
let line = CTLineCreateWithAttributedString(attributedString)
let stringRect = CTLineGetImageBounds(line, ctx)
ctx.textPosition = CGPoint(x: bounds.maxX - stringRect.width - margin,
y: bounds.minY + margin)
CTLineDraw(line, ctx)
ctx.restoreGState()
}
}
Cheers :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With