1. 程式人生 > >【Mac】獲取NSString字串高度-限定最大寬度

【Mac】獲取NSString字串高度-限定最大寬度

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;
}