【Mac】获取NSString字符串高度-限定最大宽度

本文提供了三种计算NSAttributedString和NSString在给定宽度下的高度的方法:利用NSTextStorage、NSLayoutManager和NSTextContainer计算NSAttributedString的高度;使用NSLayoutManager计算NSString的高度;通过boundingRectWithSize计算NSAttributedString的高度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值