简体   繁体   English

如何在 CGContext 中绘制字符串?

[英]How to draw String in CGContext?

I am trying to draw a string in the overriden draw method of CALayer (I'm programming for iOS).我正在尝试在CALayer的覆盖draw方法中绘制一个字符串(我正在为 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.我知道有一个CATextLayer但我需要直接绘制字符串。 How are you supposed to draw a string in CGContext in the Swift 4 era?在 Swift 4 时代,你应该如何在CGContext中绘制字符串? 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.这里的关键是您没有将 CGContext 设为当前的。 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.不幸的是,它不能在屏幕外位图或 CALayer 上下文中工作。

The right and universal way to draw a string in any CGContext is to use the CoreText api.在任何 CGContext 中绘制字符串的正确且通用的方法是使用CoreText api。 It will work on all Apple platforms, and has a lot of power under the hood.它将适用于所有 Apple 平台,并具有强大的内部功能。

https://developer.apple.com/documentation/coretext 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 :)干杯:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM