1. 计算NSAttributedString的字符串高度
- (NSSize)sizeForWidth:(float)width height:(float)height {
NSSize answer = NSZeroSize ;
if ([self length] > 0) {
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] ;
// Adjust if there is extra height for the cursor
NSSize extraLineSize = [layoutManager extraLineFragmentRect].size ;
if (extraLineSize.height > 0) {
answer.height -= extraLineSize.height ;
}
[layoutManager release] ;
// In case we changed it above, set typesetterBehavior back
// to the default value.
gNSStringGeometricsTypesetterBehavior = NSTypesetterLatestBehavior ;
answer.height += 3;
}
return answer ;
}
2. 计算普通字符高度
来自官网的推荐算法(但没有考虑NSParagraphStyleAttributeName属性,会导致不够准确)
+(NSSize)sizeOfString:(NSString*)str withGivenFont:(NSFont*)font andGivenWidth:(CGFloat)width
{
NSTextStorage *textStorage = [[[NSTextStorage alloc] initWithString:str] autorelease];
NSTextContainer *textContainer = [[[NSTextContainer alloc] initWithContainerSize: NSMakeSize(width, FLT_MAX)] autorelease];
NSLayoutManager *layoutManager = [[[NSLayoutManager alloc] init] autorelease];
[layoutManager addTextContainer:textContainer];
[textStorage addLayoutManager:layoutManager];
[textStorage addAttribute:NSFontAttributeName value:font
range:NSMakeRange(0, [textStorage length])];
[textContainer setLineFragmentPadding:0.0];
(void) [layoutManager glyphRangeForTextContainer:textContainer];
CGFloat height = [layoutManager usedRectForTextContainer:textContainer].size.height;
return NSMakeSize(width, height);
}
3. 使用boundingRectWithSize
+ (CGSize)getStringRect:(NSAttributedString*)aString width:(CGFloat)width height:(CGFloat)height
{
NSMutableAttributedString *atrString = [[NSMutableAttributedString alloc] initWithAttributedString:aString];
NSRange range = NSMakeRange(0, atrString.length);
NSDictionary* dic = [atrString attributesAtIndex:0 effectiveRange:&range];
NSFont *font = dic[NSFontAttributeName];
NSMutableDictionary *attDic = [NSMutableDictionary dictionaryWithDictionary:dic];
[attDic setObject:font forKey:NSFontAttributeName];
NSMutableParagraphStyle *paragraphStyle = dic[NSParagraphStyleAttributeName];
[attDic setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
NSRect rect = [aString boundingRectWithSize:CGSizeMake(width, height) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading];
[atrString release];
return rect.size;
}