Label根據內容計算大小

引言

由于最近工作需要實現一個類似脈脈動態的界面,其中展開顯示全文功能,需要動態計算Label的大小后決定隱藏或者顯示,之前一直使- (CGSize)sizeWithFont:(UIFont *)font方法,而在iOS7中用方法- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(nullable NSDictionary<NSString *, id> *)attributes context:(nullable NSStringDrawingContext *)context,但是在實際運用中發現還是有一點小誤差的。

關鍵字:全文Label高度計算展開全文

1 函數介紹

1.1 描述

- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary<NSString *,id> *)attributes context:(NSStringDrawingContext *)context;

根據上下文設定和顯示特性計算并返回一個rect大小

1.2 參數

參數 說明
size 存放字符串的Label的size大小
options 字符串排版的選項(下文會說明)
attributes 文字屬性設置,至少需要font屬性
context 渲染上下文

1.2.1 關于options

options 說明
NSStringDrawingTruncatesLastVisibleLine 如果文本內容超出指定的矩形限制,文本將被截去并在最后一個字符后加上省略號。
NSStringDrawingUsesLineFragmentOrigin 啟用自動換行
NSStringDrawingUsesFontLeading 計算行高時使用行間距
NSStringDrawingUsesDeviceMetrics 計算布局時使用圖元字形(而不是印刷字體)
  • 一般我們使用NSStringDrawingUsesLineFragmentOriginNSStringDrawingUsesFontLeading即可。

2 使用

直接上代碼

NSString *contentText = @"南美足聯同意國民競技隊請求,沙佩科恩斯隊將獲南美杯冠軍。南美足聯同意國民競技隊請求,沙佩科恩斯隊將獲南美杯冠軍。南美足聯同意國民競技隊請求,沙佩科恩斯隊將獲南美杯冠軍。";

UILabel *DisplayLabel = [[UILabel alloc] init];
DisplayLabel.numberOfLines = 0;
DisplayLabel.text = contentText;
DisplayLabel.textColor = [UIColor orangeColor];
DisplayLabel.font = [UIFont systemFontOfSize:17];
DisplayLabel.frame = CGRectMake(20, 70, 200, 200);
[DisplayLabel sizeToFit];
DisplayLabel.backgroundColor = [UIColor greenColor];
[self.view addSubview:DisplayLabel];
    
//至少設置一個font屬性
UIFont *fnt = self.DisplayLabel.font;
NSDictionary *dict = @{NSFontAttributeName: fnt};
    
//在為達到高度的情況下只有label的寬度有約束作用,高度最多為1000
CGSize defineSize = CGSizeMake(DisplayLabel.bounds.size.width, 1000);
//rect內的size即為計算所得的label大小
CGRect rect = [contentText boundingRectWithSize:defineSize
                                            options:NSStringDrawingUsesLineFragmentOrigin | 
                                                    NSStringDrawingUsesFontLeading
                                         attributes:dict
                                            context:nil];

結果顯示

Simulator Screen Shot 2016年12月3日 下午3.00.13.png
  • 結果上會有小數點后一位的誤差,需要各位爺自己調整下,如果有好的建議歡迎指教~

3 附加

  • 展開顯示全文的功能有時候還能通過計算行數來實現,送上一個coreText下的計算行數及每行內容的方法
//數組內為每行的內容,數組的count為行數
- (NSArray *)getLinesArrayOfStringInLabel:(UILabel *)label{
    NSString *text = [label text];
    UIFont *font = [label font];
    //目的為了取到label的寬度
    CGRect rect = [label frame];
    
    CTFontRef myFont = CTFontCreateWithName(( CFStringRef)([font fontName]), [font pointSize], NULL);
    NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:text];
    [attStr addAttribute:(NSString *)kCTFontAttributeName value:(__bridge  id)myFont range:NSMakeRange(0, attStr.length)];
    CFRelease(myFont);
    CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString(( CFAttributedStringRef)attStr);
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, CGRectMake(0,0,rect.size.width,100000));
    CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, NULL);
    NSArray *lines = ( NSArray *)CTFrameGetLines(frame);
    NSMutableArray *linesArray = [[NSMutableArray alloc]init];
    for (id line in lines) {
        CTLineRef lineRef = (__bridge  CTLineRef )line;
        CFRange lineRange = CTLineGetStringRange(lineRef);
        NSRange range = NSMakeRange(lineRange.location, lineRange.length);
        NSString *lineString = [text substringWithRange:range];
        CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attStr, lineRange, kCTKernAttributeName, (CFTypeRef)([NSNumber numberWithFloat:0.0]));
        CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attStr, lineRange, kCTKernAttributeName, (CFTypeRef)([NSNumber numberWithInt:0.0]));
        [linesArray addObject:lineString];
    }
    CFRelease(frameSetter);
    CFRelease(frame);
    CFRelease(path);
    return (NSArray *)linesArray;
}


最后附上github的demo
歡迎各位看官老爺指教~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容