在實際的項目開發中,UI出的設計圖中會標示文本顯示的上下左右邊距,效果相似下圖:
(單行無行間距)app
(多行涉及行間距)字體
紫色箭頭標示的是文本距離背景的上下左右四個方向的距離值,深色區域實際爲須要顯示文本的控件大小spa
有時會遇到這種場景,顯示文本控件大小的frame是按照UI出圖的標記值設置,但是當UI走查的時卻被打回,緣由是標記值沒有按照標記值設置。緣由主要就是由於控件的邊框沒有和文字內容徹底貼邊,以下圖(文本邊緣距離顯示控件邊緣有距離):設計
解決此種問題的方法主要就是讓兩者的邊緣貼合。code
下面以UILabel爲例說明解決方法,分兩種狀況:一行顯示和多行顯示(涉及行間距)ci
/** * 動態計算消息的高度 * @param text 文本內容 * @param font 字體大小 * @param maxWidth 最大寬度 * @return 計算後的消息高度 */ - (CGFloat)calculateSinglePicTextMsgLabelHeight:(NSString *)text font:(UIFont *)font maxWidth:(CGFloat)maxWidth { CGFloat height = 0; if (text.length > 0) { NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; NSDictionary *attribute = @{NSFontAttributeName:font, NSParagraphStyleAttributeName:paragraphStyle.copy}; CGSize size = [text boundingRectWithSize:CGSizeMake(maxWidth, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attribute context:nil].size; // 獲得單行文本高度(此處也能夠用font.lineHeight屬性獲取) CGFloat singleLineHeight = [self setMaxNumberOfLines:1 font:font maxWidth:maxWidth]; double titleRow = ceil((size.height * 0.1) / (singleLineHeight * 0.1)); height = singleLineHeight * titleRow + kLineSpace * (titleRow - 1); } return height; } /** * 動態計算消息內容須要顯示的行數 * @param text 文本內容 * @param font 字體大小 * @param maxWidth 最大寬度 * @return 計算後的消息須要顯示的行數 */ - (NSInteger)numberOfLinesToShowText:(NSString *)text font:(UIFont *)font maxWidth:(CGFloat)maxWidth { if (text.length > 0) { NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; NSDictionary *attribute = @{NSFontAttributeName:font, NSParagraphStyleAttributeName:paragraphStyle.copy}; CGSize size = [text boundingRectWithSize:CGSizeMake(maxWidth, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attribute context:nil].size; // 獲得單行文本高度(此處也能夠用font.lineHeight屬性獲取) CGFloat singleLineHeight = [self setMaxNumberOfLines:1 font:font maxWidth:maxWidth]; return ceil((size.height * 0.1) / (singleLineHeight * 0.1)); } return 0; } // 獲得控件的大小 CGFloat titleHeight = [sinPicTxt calculateSinglePicTextMsgLabelHeight:content.title font:[UIFont fontWithName:@"Arial" size:kTitleFont] maxWidth:msgBodyViewWidth - kSPublicBubleLeftMargin * 2]; // 獲得文本內容須要顯示的行數 NSInteger titleNumberLines = [sinPicTxt numberOfLinesToShowText:content.title font:[UIFont fontWithName:@"Arial" size:kTitleFont] maxWidth:msgBodyViewWidth - kSPublicBubleLeftMargin * 2]; _titleLab.frame = CGRectMake(_titleLab.frame.origin.x, _titleLab.frame.origin.y, msgBodyViewWidth - kSPublicBubleLeftMargin * 2, titleHeight); // 設置label的行間距 NSMutableAttributedString *titleAttributedString = [[NSMutableAttributedString alloc] initWithString:content.title attributes:@{NSFontAttributeName:_titleLab.font}]; NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; [paragraphStyle setLineSpacing:titleNumberLines > 1 ? kLineSpace : kLineSpaceZero]; [paragraphStyle setLineBreakMode:NSLineBreakByTruncatingTail]; [titleAttributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [content.title length])]; [_titleLab setAttributedText:titleAttributedString];