iOS:如何使用 Quartz 测量字符串的宽度和高度?
在我提出问题之前,这是来自 Apple 的文档:如何使用 Quartz 确定字符串的宽度:
如果文本测量对您的应用很重要,那么可以 使用 Quartz 2D 函数计算它们。 但是,您可能首先 考虑使用 ATSUI,其优势在于文本布局和 测量。 ATSUI 有多个获取文本指标的函数。 不是 只能获得布局后的文本指标,但在极少数情况下 如果您需要它们,您可以获取布局前的文本指标。 不像 Quartz,您必须自己执行计算,ATSUI 为您计算测量值。 例如,您可以获得 通过调用 ATSUI 函数为文本设置图像边界矩形 ATSUMeasureTextImage。
如果您认为 Quartz 文本比 ATSUI(或 Cocoa),您可以按照以下步骤测量文本的宽度 石英绘制它:
- 调用函数CGContextGetTextPosition获取当前文本位置。
- 使用函数 CGContextSetTextDrawingMode 将文本绘制模式设置为 kCGTextInvisible。
- 绘制文本,通过调用函数CGContextShowText在当前文本位置绘制文本。
- 通过调用函数 CGContextGetTextPosition 确定最终文本位置。
- 从结束位置减去开始位置即可确定文本的宽度。
这是我的问题:
这真的是使用 Core Graphics 确定字符串宽度的最佳方法吗? 它看起来很脆弱,而且由于我的文本与 2D 图形元素共存,我想对所有渲染使用相同的上下文。 我希望有一些紧凑的方法,例如:
CGContextGetTextWidthAndHeight(上下文,文本);
我读到 ATSUI 已经过时并且将被 Core Text 取代。 这是真的吗?如果是,iOS 中也是如此吗?
Before I ask my questions, this is from Apple's documentation re: how to determine the width of a string using Quartz:
If text measurements are important to your application, it is possible
to calculate them using Quartz 2D functions. However, you might first
consider using ATSUI, whose strength is in text layout and
measurement. ATSUI has several functions that obtain text metrics. Not
only can you obtain after-layout text metrics, but in the rare cases
you need them, you can obtain before-layout text metrics. Unlike
Quartz, for which you must perform the calculations yourself, ATSUI
computes the measurements for you. For example, you can obtain the
image bounding rectangle for text by calling the ATSUI function
ATSUMeasureTextImage.If you decide that Quartz text suits your needs better than ATSUI (or
Cocoa), you can follow these steps to measure the width of text before
Quartz draws it:
- Call the function CGContextGetTextPosition to obtain the current text position.
- Set the text drawing mode to kCGTextInvisible using the function CGContextSetTextDrawingMode.
- Draw the text by calling the function CGContextShowText to draw the text at the current text position.
- Determine the final text position by calling the function CGContextGetTextPosition.
- Subtract the starting position from the ending position to determine the width of the text.
Here are my questions:
Is this really the best way to determine the width of a string using Core Graphics? It seems flimsy and since my text co-exists with 2D graphical elements, I'd like to use the same context for all rendering. I was hoping there would be some compact method, like:
CGContextGetTextWidthAndHeight(context, text);
I read that ATSUI is outdated and going to be replaced by Core Text. Is that true and if so, is it in iOS?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 iPhone SDK 上,
NSString
上有一系列方法可以提供您想要的功能。从 iOS 7.0 开始,这些方法是:
在旧版本的 iOS 上,我们有这些,现在已弃用:
On the iPhone SDK, there's a family of methods on
NSString
that provide what you want.As of iOS 7.0, these methods are:
On older versions of iOS we had these, now deprecated:
在 UI 线程以外的线程上执行绘图操作时,必须使用您所描述的技术。 当使用像 CATiledLayer 这样的东西时,这一点尤其需要注意,它在后台线程上异步执行渲染,或者由于任何其他原因在后台绘制自定义图形时。
当你做“简单”图形并且保证在主线程上运行时,我同意 PGB。 然而, sizeWithFont 正在做与您描述的技术相同的事情 - 它只是使用 UIGraphicsGetCurrentContext() 为您做这件事。
When performing drawing operations on threads other than the UI thread, you must use the technique you described. This is especially important to note when using things like CATiledLayer, which performs it's rendering asynchronously on background threads, or when drawing custom graphics in the background for any other reason.
I agree with PGB when you're doing "simple" graphics and you are guaranteed to be running on the main thread. However, sizeWithFont is doing the same thing as the technique you described - it's simply doing it for you using UIGraphicsGetCurrentContext().