How to draw String in CGContext?

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 = [.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 :)