【Mac】獲取NSString字串高度-限定最大寬度
阿新 • • 發佈:2018-12-09
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; }