*准确*计算Cocoa中的文本高度(适用于Mac,不适用于iOS)

Enc*_*ada 11 macos cocoa objective-c

对于某些给定的固定宽度,如何计算特定标签(NSTextField)中字符串的高度?

我尝试了谷歌搜索各种方法.我试过这个方法:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/TextLayout/Tasks/StringHeight.html

它的工作原理,除了高度变成一条线太长以至于较长的弦.因此,在本方法中似乎存在一些不准确之处.

我也遇到了与谷歌搜索的其他代码相同的问题.

这里有人有任何准确的代码来查找文本高度(给定特定宽度)?

Enc*_*ada 19

我使用http://www.sheepsystems.com/sourceCode/sourceStringGeometrics.html提供的NS(归因)String + Geometrics类别解决了这个问题.在该类别的头文件中,这是对这些内容如何工作的一个很好的解释.具体来说,他们提到应该使用NSTextView而不是NSTextField,因为实际上不可能为后者获得准确的高度.

因此,我用NSTextView替换了我的NSTextField.首先,我使用以下代码使我的NSTextView看起来像我的NSTextField:

[textView setEditable:YES];
[textView insertText:someString];
[textView setFont:[NSFont fontWithName:@"Lucida Grande"
   size:11] range:NSMakeRange(0,[someString length])];
[textView setEditable:NO];
[textView setSelectable:NO];
Run Code Online (Sandbox Code Playgroud)

然后我用这段代码得到了高度:

NSDictionary *attributes
  = [NSDictionary dictionaryWithObjectsAndKeys:
     [textView font],NSFontAttributeName,nil];
NSAttributedString *attributedString
  = [[NSAttributedString alloc] initWithString:
     [textView string] attributes:attributes];
CGFloat height = [attributedString heightForWidth:
                 [textView frame].size.width];
Run Code Online (Sandbox Code Playgroud)

对于NSTextView,高度确实是准确的.

我可能已经省略了一些细节,但是你得到了图片.我希望这可以帮助那里的人.


vig*_*ing 7

(Swift的解决方案在帖子的最后)

我尝试了所有这些方法,但没有一个适合我.我所说的"正式"方式(如OP所述)在大部分时间都没有NSTextField.切换到NSTextView不可能,因为在NSScrollView中添加"NSTextView"后,XCode/IB 总是崩溃.

长话短说,我找到了这种简单的方法来确定我的高度,NSTextField但这很容易适应宽度.

CGFloat minHeight = [((NSTextFieldCell *)[yourTextField cell]) cellSizeForBounds:NSMakeRect(0, 0, YOUR_MAX_WIDTH, FLT_MAX)].height;
Run Code Online (Sandbox Code Playgroud)

此代码适用于使用其他方法失败的每个测试用例.我希望这可以帮助别人.当我花2个小时找到一个看似简单的问题的解决方案时,它总是让我感到非常愚蠢.

SLIGHT编辑:经仔细检查这只能如果你看过stringValueNSTextField之前,我问电池来计算其高度.所以我在实际计算之前添加了以下无意义的行:

[yourTextField setStringValue:yourTextField.stringValue];
Run Code Online (Sandbox Code Playgroud)

我知道这真的很糟糕,但此时我不在乎了.我只想要一个可靠的解决方案.请随意向我推荐或更好:建议一个更好的解决方案.


Swift中的解决方案(谢谢iphaaw将此引起我的注意!)

myTextField.cell!.cellSizeForBounds(NSMakeRect(CGFloat(0.0), CGFloat(0.0), width, CGFloat(FLT_MAX))).height
Run Code Online (Sandbox Code Playgroud)


Art*_*KGH 5

确实感谢 iphaaw 和 Enchilada 提供了这个非常酷的小解决方案。我发现它在设置行高等方面效果很好,因此我将 iphaaw 的 Swift 转换为几个 NSTextField 扩展。享受

extension NSTextField {
func bestheight(text: String, width: CGFloat) -> CGFloat {

    self.stringValue = text
    let getnumber = self.cell!.cellSizeForBounds(NSMakeRect(CGFloat(0.0), CGFloat(0.0), width, CGFloat(FLT_MAX))).height

    return getnumber
   }
}

extension NSTextField {
func bestwidth(text: String, height: CGFloat) -> CGFloat {

    self.stringValue = text
    let getnumber = self.cell!.cellSizeForBounds(NSMakeRect(CGFloat(0.0), CGFloat(0.0), CGFloat(FLT_MAX), height)).width

    return getnumber
   }
}
Run Code Online (Sandbox Code Playgroud)

我希望有人觉得这些有用。关于 KGH