好的,这是我的情况:
- 我有一个
NSTextField
,设置为多行文本标签 NSTextField
应该只保存一行文本(即使它是多行文本)NSTextField
具有固定高度。
字体- 和字体大小由用户更改
问题 :
- 根据使用的字体和大小,文本的底部会丢失(因为它超出了
NSTextField
的边界
我想要什么 :
- 根据选择获取文本高度(字体和字体大小),并相应地设置
NSTextField
的高度。
我知道这听起来可能很复杂,但我也知道这是可以做到的。
有什么想法吗?有什么参考可以指点我吗?
如前所述,NSTextField 和 UITextField 是非常不同的对象(与它们的名字所暗示的相反)。具体来说,对于NSTextField,你可以使用一个涉及NSLayoutManager的优雅解决方案。NSLayoutManager 对象协调 NSTextStorage 对象中保存的字符的布局和显示。它将 Unicode 字符代码映射到字形,在一系列 NSTextContainer 对象中设置字形,并在一系列 NSTextView 对象中显示它们。
您所需要的只是创建一个NSLayoutManager,NSTextContainer和NSTextStorage。它们以类似的方式包装在一起:
.-----------------------.
| NSTextStorage |
| .-----------------. |
| | NSLayoutManager | |
| '-----------------' |
| | NSTextStorage | |
| '-----------------' |
| |
'-----------------------'
也就是说,您可以使用布局管理器方法usedRectForTextContainer:
来估计包含所需文本的正确大小。
以下内容应该适用于您的问题:
- (float)heightForStringDrawing:(NSString *)aString withFont:(NSFont *)aFont andWitdh:(float)myWidth
{
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithString:aString];
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithContainerSize:NSMakeSize(myWidth,CGFLOAT_MAX)];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
[layoutManager setTypesetterBehavior:NSTypesetterBehavior_10_2_WithCompatibility];
[layoutManager addTextContainer:textContainer];
[textStorage addLayoutManager:layoutManager];
[textStorage addAttribute:NSFontAttributeName value:aFont
range:NSMakeRange(0,[textStorage length])];
[textContainer setLineFragmentPadding:0.0];
NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
[layoutManager drawGlyphsForGlyphRange: glyphRange atPoint:NSMakePoint(0, 0)];
return [layoutManager usedRectForTextContainer:textContainer].size.height;
}
有一个关于这个主题的详尽的Apple文档:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TextLayout/Tasks/StringHeight.html#//apple_ref/doc/uid/20001809-CJBGBIBB
此外,一些退伍军人前段时间在Apple邮件列表中剖析了这个问题:
http://lists.apple.com/archives/cocoa-dev/2006/Jan/msg01874.html
正如@valvoline所说,这是有效的,但是如果你在drawRect之外执行此操作,你会得到很多CGContext警告,比如CGContextGetFontRenderingStyle: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
。最好的解决方案是不要使用drawGlyphsForGlyphRange:正如苹果文档 https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/TextLayout/Tasks/StringHeight.html#//apple_ref/doc/uid/20001809-CJBGBIBB 所讲述的那样。
您可以获取字符串的大小,然后相应地更改高度
NSString *text = // your string
CGSize constraint = CGSizeMake(210, 20000.0f);
CGSize size = [text sizeWithFont:[UIFont fontWithName:@"Helvetica-Light" size:14] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
UITextField *cellTextLabel = [[UITextField alloc] initWithFrame:CGRectMake(70, 9, 230, size.height)];
cellTextLabel.lineBreakMode = UILineBreakModeWordWrap;
cellTextLabel.numberOfLines = 50;
cellTextLabel.backgroundColor = [UIColor clearColor];
cellTextLabel.text = text;
cellTextLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:14];
[self.view addSubview:cellTextLabel];
[cellTextLabel release];