Cocoa NSString BOUNDINGRECTIZE稍微低估了正确的宽度-为什么?
我正在创建一个类,该类显示一个窗口,其中包含一些文本、一个“不再显示”复选框和一个按钮。为了可重用,该类根据需要调整窗口大小以适应文本 然而,在计算中有一些轻微的不精确性-如果我不在宽度上添加5个像素,一些字符串会被截断。(最后一个单词被简单删除。) 以下是我所拥有的:Cocoa NSString BOUNDINGRECTIZE稍微低估了正确的宽度-为什么?,cocoa,Cocoa,我正在创建一个类,该类显示一个窗口,其中包含一些文本、一个“不再显示”复选框和一个按钮。为了可重用,该类根据需要调整窗口大小以适应文本 然而,在计算中有一些轻微的不精确性-如果我不在宽度上添加5个像素,一些字符串会被截断。(最后一个单词被简单删除。) 以下是我所拥有的: // NSTextField *textLabel; // NSString *text; NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject:
// NSTextField *textLabel;
// NSString *text;
NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject: [textLabel font] forKey: NSFontAttributeName];
NSRect textFrame = [text boundingRectWithSize:NSMakeSize(textLabel.frame.size.width, (unsigned int)-1)
options:(NSStringDrawingDisableScreenFontSubstitution | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
attributes:stringAttributes];
textFrame.size.width += 5;
我临时将标签的背景颜色设置为黄色,以使调试更容易,并且它明显地扩展到几乎适合最后一个单词。在该测试字符串上增加4个像素就足够了。请注意,如果没有这些添加的像素,并非所有字符串都会失败 我关心的原因有两个:
1) 我想知道为什么它有点错,更重要的是
2) 我认为,通过在计算后改变宽度,包装理论上可以改变,并保留未使用的最后一行,在文本下方创建额外的空白。在过去几年中,我曾多次遇到过同样的问题,每当我需要使用该方法时都会遇到。我从未发现任何关于这件事的信息,但多年来我收集到的是,问题似乎是字符串越短,宽度就越不准确。经过足够长的长度后,他们使用的方程几乎是完美的,但在此之前,它是可怕的。为什么,我从来没有找到一个解释 在我试图解决这个问题的过程中,我尝试过添加平面值和乘以常量,但这些都没有给出完美的结果 最近,我一直在使用
width *= (25/(width+2)+1);
使用NSStringDrawingUserDeviceMetrics。对于我常用的长度,这给了我不错的结果。我已经看到8-50个字符之间的字符串的最大1-2像素差异,这对于我的要求足够精确。50个字符后,boundingRectWithSize:options:attributes:更加精确,但并不完美。我还没有对它进行足够广泛的测试,不能说得更多。这就是说,这应该消除任何担心下面有另一行,因为文本永远不应该下降到另一行。在更高的范围内(没有测试过300个字符),它会稍微高估而不是低估。如果它再次开始低估,请将25增加到~30。我发现通过其
cellSizeForBounds:
方法查询NSTextFieldCell
比使用boundingRectWithSize:在给定固定宽度的情况下确定文本高度更准确。您可能会发现,在您的情况下,它更适用于估计宽度。(我使用的是Mountain Lion,所以我不确定它在早期SDK中是如何运行的。)
请参阅我的答案。将结果用ceilf()包装,以便将值向上舍入到下一个整数。这有很大的不同