在实际的项目开发中,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];