15

我正在尝试根据当前宽度自动调整文本字段/视图的大小。换句话说,我希望宽度保持不变,但根据提供给它的文本调整高度。

它似乎正在工作,但由于某种原因,它与我的窗口底部对齐,尽管努力手动将其移回。谁能看到我在这里做错了什么?

在此处输入图像描述

NSString *temp = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vel felis nec massa ultricies blandit non id arcu. Sed enim est, facilisis a feugiat in, consectetur eget arcu. Aenean rutrum, lacus id euismod congue, nisl erat vulputate lectus, non faucibus tortor purus sed sem. Donec tempor dui egestas velit auctor vitae faucibus diam facilisis. Morbi convallis nulla quis est pulvinar quis ultricies sem sollicitudin.";

myText.stringValue = temp;

NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
                            [NSFont systemFontOfSize:12], NSFontAttributeName,
                            [NSParagraphStyle defaultParagraphStyle], NSParagraphStyleAttributeName,
                            nil];

NSSize size = NSMakeSize(window.frame.size.width, 200);
myText.frame = [temp boundingRectWithSize:size options:NSLineBreakByWordWrapping | NSStringDrawingUsesLineFragmentOrigin attributes:attributes];

编辑:即使手动移动框架,很明显文本仍然被截断。新调整的尺寸并不完全在那里。 在此处输入图像描述

这是参考: NSString boundingRectWithSize 稍微低估了正确的宽度 - 为什么?NSTextView 或 NSTextField 自动调整边界/框架的大小?

4

4 回答 4

25

我有同样的问题。我在文档中找到了以下内容:

要正确绘制多行文本并调整其大小,请在 options 参数中传递 NSStringDrawingUsesLineFragmentOrigin。

此方法返回小数大小(在返回的 CGRect 的大小分量中);要使用返回的大小来调整视图大小,您必须使用 ceil 函数将其值提高到最接近的较高整数。

所以这为我解决了这个问题:

CGRect rect = [myLabel.text boundingRectWithSize:CGSizeMake(myLabel.frame.size.width, CGFLOAT_MAX)
                                                            options:NSStringDrawingUsesLineFragmentOrigin
                                                            attributes:@{NSFontAttributeName: myLabel.font}
                                                            context:nil];
rect.size.width = ceil(rect.size.width);
rect.size.height = ceil(rect.size.height);

更新(斯威夫特 5.1)

另一种 Swift 方法是:

let size = myLabel.text!.size(
    withAttributes: [.font: myLabel.font!]
)
let rect = CGSize(
  width: ceil(size.width),
  height: ceil(size.height)
)

有关Objective-C 示例,请参阅此答案。

于 2014-05-09T11:11:02.853 回答
2

这有点迂回,但我发现查询NSTextFieldCell比使用[NSAttributedString boundingRectWithSize:options:].

假设感兴趣的字符串已经在一个 NSTextField 中,并且设置了适当的格式/换行选项,然后查询文本单元格它认为它需要适合指定宽度的大小:

NSTextField* textField = ...

NSSize cellSize = [textField.cell cellSizeForBounds:NSMakeRect(0, 0, pathText.frame.size.width, CGFLOAT_MAX)];

cellSize.height给出文本在绘制时实际使用的高度。

于 2012-11-07T01:31:46.593 回答
1

这就是我最终的结果(至少目前是这样),它似乎工作正常,但我仍然觉得有更好的方法来实现这一点。

NSString *temp = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vel felis nec massa ultricies blandit non id arcu. Sed enim est. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vel felis nec massa ultricies blandit non id arcu. Sed enim est.";

myText.stringValue = temp;

NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
                            [NSFont systemFontOfSize:12], NSFontAttributeName,
                            [NSParagraphStyle defaultParagraphStyle], NSParagraphStyleAttributeName,
                            nil];

NSSize size = NSMakeSize(window.frame.size.width, MAXFLOAT);


myText.frame = [temp boundingRectWithSize:size options:NSLineBreakByWordWrapping | NSStringDrawingUsesLineFragmentOrigin attributes:attributes];

// Keep current width but add some more on the bottom
NSSize tF = myText.frame.size;
[myText setFrameSize:NSMakeSize(tF.width, tF.height + 35)];

[myText setFrameOrigin:NSMakePoint((NSWidth(window.frame) - NSWidth(myText.frame)) / 2, 
                                   (NSHeight(window.frame) -  NSHeight(myText.frame) - 20))];

[myText setAutoresizingMask:NSViewMinXMargin | NSViewMaxXMargin | NSViewMinYMargin | NSViewMaxYMargin];

产生这个:

在此处输入图像描述

于 2012-08-23T23:27:50.800 回答
1

我发现 NSString#boundingRectWithSize 从来都不是完全正确的,唯一似乎运作良好的是这里描述的那个: https ://developer.apple.com/library/content/documentation/Cocoa/Conceptual/TextLayout/Tasks/StringHeight .html

class func sizeForString(_ text : String, withFont font: NSFont, inWidth maxWidth: CGFloat) -> NSSize {
    let textStorage = NSTextStorage(string: text)
    let textContainer = NSTextContainer(containerSize: NSSize(width: maxWidth, height: CGFloat.greatestFiniteMagnitude))
    let layoutManager = NSLayoutManager()
    layoutManager.addTextContainer(textContainer)
    textStorage.addLayoutManager(layoutManager)
    textStorage.addAttribute(NSFontAttributeName, value: font, range: NSMakeRange(0, textStorage.length))
textContainer.lineFragmentPadding = 0
    layoutManager.glyphRange(for: textContainer)
    return layoutManager.usedRect(for: textContainer).size
 }
于 2017-08-10T13:49:26.980 回答