测量可可中的绳子高度
我正在寻找一个高度测量字符串程序,我在另一个堆栈溢出问题上找到了这个程序。它非常适合我的 NSTableViewColumns,它具有自动换行作为换行符 我的问题是,如果我将换行符更改为字符换行怎么办,如何更新此代码?
- (NSSize)sizeForWidth:(float)width
height:(float)height {
NSSize answer = NSZeroSize ;
gNSStringGeometricsTypesetterBehavior = NSTypesetterBehavior_10_2_WithCompatibility;
if ([self length] > 0) {
// Checking for empty string is necessary since Layout Manager will give the nominal
// height of one line if length is 0. Our API specifies 0.0 for an empty string.
NSSize size = NSMakeSize(width, height) ;
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithContainerSize:size] ;
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:self] ;
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init] ;
[layoutManager addTextContainer:textContainer] ;
[textStorage addLayoutManager:layoutManager] ;
[layoutManager setHyphenationFactor:0.0] ;
if (gNSStringGeometricsTypesetterBehavior != NSTypesetterLatestBehavior) {
[layoutManager setTypesetterBehavior:gNSStringGeometricsTypesetterBehavior] ;
}
// NSLayoutManager is lazy, so we need the following kludge to force layout:
[layoutManager glyphRangeForTextContainer:textContainer] ;
answer = [layoutManager usedRectForTextContainer:textContainer].size ;
[textStorage release] ;
[textContainer release] ;
[layoutManager release] ;
// In case we changed it above, set typesetterBehavior back
// to the default value.
gNSStringGeometricsTypesetterBehavior = NSTypesetterLatestBehavior ;
}
return answer ;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这感觉就像您正在重新发明
[NSAttributedStringboundingRectWithSize:options:]
(或只是size
)。我在你的实施中遗漏了一些东西吗? NSLayoutManager 用于处理快速变化的字符串布局(例如在文本视图中)。大多数时候,这是多余的。您故意绕过它的优化(在您的行中注意到NSLayoutManager
是懒惰的,这意味着您已优化:D)无论哪种情况,要更改包装行为,您都需要修改
NSAttributedString 本身。换行是段落样式。像这样的东西(未经测试;可能无法编译):
样式有点棘手,因为它们包含几项内容,但您必须将它们全部设置在一起。因此,如果属性字符串中有不同的样式,则必须循环该字符串,处理每个
effectiveRange 。 (您需要阅读文档以了解
attributesAtIndex: effectiveRange:
和attributesAtIndex:longestEffectiveRange:inRange:
之间的权衡。)This feels like you're reinventing
[NSAttributedString boundingRectWithSize:options:]
(or justsize
). Am I missing something in your implementation?NSLayoutManager
is for dealing with laying out rapidly-changing strings (such as in a text view). Most of the time it's overkill. You're intentionally bypassing its optimizations (in your line noting thatNSLayoutManager
is lazy, by which you mean optimized :D)In either case, to change the wrapping behavior, you need to modify the
NSAttributedString
itself. Wrapping is part of the paragraph style. Something like this (untested; might not compile):Styles are a little tricky because they include several things in them, but you have to set them all together. So if there were different styles in the attributed string, you have to loop over the string, processing each
effectiveRange
. (You'd want to read the docs to understand the tradeoff betweenattributesAtIndex:effectiveRange:
andattributesAtIndex:longestEffectiveRange:inRange:
.)