iOS:如何使用 Quartz 测量字符串的宽度和高度?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/913470/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS: How do you measure the width and height of a string using Quartz?
提问by Hunter D
Before I ask my questions, this is from Apple's documentation re: how to determine the width of a string using Quartz:
在我问我的问题之前,这是来自 Apple 的文档 re:如何使用 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.
如果文本测量对您的应用很重要,则可以使用 Quartz 2D 函数进行计算。但是,您可能首先考虑使用 ATSUI,其优势在于文本布局和度量。ATSUI 有几个获取文本度量的函数。您不仅可以获得布局后的文本指标,而且在极少数需要它们的情况下,您还可以获得布局前的文本指标。与必须自己执行计算的 Quartz 不同,ATSUI 会为您计算测量值。例如,您可以通过调用 ATSUI 函数 ATSUMeasureTextImage 获取文本的图像边界矩形。
如果您认为 Quartz 文本比 ATSUI(或 Cocoa)更适合您的需求,您可以按照以下步骤在 Quartz 绘制文本之前测量文本的宽度:
- 调用函数 CGContextGetTextPosition 获取当前文本位置。
- 使用函数 CGContextSetTextDrawingMode 将文本绘制模式设置为 kCGTextInvisible。
- 通过调用函数 CGContextShowText 在当前文本位置绘制文本来绘制文本。
- 通过调用函数 CGContextGetTextPosition 确定最终文本位置。
- 从结束位置减去开始位置以确定文本的宽度。
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?
这真的是使用 Core Graphics 确定字符串宽度的最佳方法吗?这看起来很脆弱,而且由于我的文本与 2D 图形元素共存,我想对所有渲染使用相同的上下文。我希望会有一些紧凑的方法,例如:
CGContextGetTextWidthAndHeight(context, text);
我读到 ATSUI 已过时,将被 Core Text 取代。这是真的吗?如果是,是在 iOS 中吗?
回答by pgb
On the iPhone SDK, there's a family of methods on NSString
that provide what you want.
在 iPhone SDK 上,有一系列方法NSString
可以提供您想要的东西。
As of iOS 7.0, these methods are:
从 iOS 7.0 开始,这些方法是:
- boundingRectWithSize:options:attributes:context:
- sizeWithAttributes:
On older versions of iOS we had these, now deprecated:
在旧版本的 iOS 上,我们有这些,现在已弃用:
– sizeWithFont:
– sizeWithFont:forWidth:lineBreakMode:
– sizeWithFont:constrainedToSize:
– sizeWithFont:constrainedToSize:lineBreakMode:
– sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode:
回答by Steve
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.
在 UI 线程以外的线程上执行绘图操作时,必须使用您描述的技术。在使用 CATiledLayer 之类的东西时,这一点尤其重要,它在后台线程上异步执行渲染,或者出于任何其他原因在后台绘制自定义图形时。
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().
当你在做“简单”的图形并且你保证在主线程上运行时,我同意 PGB。但是,sizeWithFont 正在做与您描述的技术相同的事情 - 它只是使用 UIGraphicsGetCurrentContext() 为您完成。