Label设置行间距
2016-07-09 21:07
405 查看
Label设置行间距
字数1607 阅读130 评论2 喜欢3
Label设置行间距
内容摘要
UILabel显示多行文本UILabel设置行间距
解决单行文本 & 多行文本显示的问题
场景描述
众所周知,UILabel显示多行的话,默认行间距为0,但实际开发中,如果显示多行文本,一般情况下会有一定的行间距。如果想动态调整行间距,则需要赋值富文本属性(而不是文本属性)
问题分析
Label显示多行文本
label默认情况下,只会显示单行文本,主要是因为它的numberOfLines属性值是
1;如果要显示多行,把这个属性值改成
0即可。
self.lblResult.numberOfLines = 0;
默认情况下,会显示成这样:
![](http://upload-images.jianshu.io/upload_images/427885-6d841ed588eb8601.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
Label设置行间距_多行0间距.png
如果想添加行间距,你可能会这样做:
写一个string转换成AttributedString的方法(或者给字符串增加一个分类)
-(NSAttributedString *)getAttributedStringWithString:(NSString *)string lineSpace:(CGFloat)lineSpace { NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string]; NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineSpacing = lineSpace; // 调整行间距 NSRange range = NSMakeRange(0, [string length]); [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range]; return attributedString; }
赋值富文本属性
NSString *string = @"众所周知,UILabel显示多行的话,默认行间距为0,但实际开发中,如果显示多行文本,一般情况下会有一定的行间距。如果想动态调整行间距,则需要赋值**富文本属性**(而不是文本属性)"; // 5:行间距 self.lblResult.attributedText = [self getAttributedStringWithString:string lineSpace:5];
结果如下图:
![](http://upload-images.jianshu.io/upload_images/427885-7bb3dbe91545ff54.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
Label设置行间距_多行5间距.png
=============== 华丽的分割线 ===============
问题:以上方法显示多行文本貌似没有问题,但如果文本只有一行呢?
Label显示单行文本
显示单行中文:NSString *string = @"文本只有一行会显示什么样?"; self.lblResult.attributedText = [self getAttributedStringWithString:string lineSpace:5];
![](http://upload-images.jianshu.io/upload_images/427885-a6f65510a0b9640b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
Label设置行间距_单行中文5间距.png
显示单行英文:
NSString *string = @"good good study day day up"; self.lblResult.attributedText = [self getAttributedStringWithString:string lineSpace:5];
![](http://upload-images.jianshu.io/upload_images/427885-e6c3cda000410c83.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
Label设置行间距_单行英文5间距1.png
通过比较发现,用同样的方法,单行显示中文 & 英文,效果不同,中文会多了一些空白!心中立马有种蛋蛋的忧桑,一丝丝凄凉……
遇到问题之后
查询API-NSMutableParagraphStyle
// Indent:缩进 @property(NS_NONATOMIC_IOSONLY) CGFloat lineSpacing; @property(NS_NONATOMIC_IOSONLY) CGFloat paragraphSpacing; @property(NS_NONATOMIC_IOSONLY) NSTextAlignment alignment; @property(NS_NONATOMIC_IOSONLY) CGFloat firstLineHeadIndent; @property(NS_NONATOMIC_IOSONLY) CGFloat headIndent; @property(NS_NONATOMIC_IOSONLY) CGFloat tailIndent; @property(NS_NONATOMIC_IOSONLY) NSLineBreakMode lineBreakMode; @property(NS_NONATOMIC_IOSONLY) CGFloat minimumLineHeight; @property(NS_NONATOMIC_IOSONLY) CGFloat maximumLineHeight; @property(NS_NONATOMIC_IOSONLY) NSWritingDirection baseWritingDirection; @property(NS_NONATOMIC_IOSONLY) CGFloat lineHeightMultiple; @property(NS_NONATOMIC_IOSONLY) CGFloat paragraphSpacingBefore; @property(NS_NONATOMIC_IOSONLY) float hyphenationFactor;
各种尝试之后,问题还在那儿……
想到富文本属性,查询
NSAttributedString.h头文件
仿佛看到了胜利的曙光
UIKIT_EXTERN NSString * const NSBaselineOffsetAttributeName NS_AVAILABLE(10_0, 7_0); // NSNumber containing floating point value, in points; offset from baseline, default 0
尝试解决问题
重构getAttributedStringWithString方法
-(NSAttributedString *)getAttributedStringWithString:(NSString *)string lineSpace:(CGFloat)lineSpace baselineOffset:(CGFloat)baselineOffset { NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string]; NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineSpacing = lineSpace; // 调整行间距 NSRange range = NSMakeRange(0, [string length]); [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range]; // 设置文本偏移量 [attributedString addAttribute:NSBaselineOffsetAttributeName value:@(baselineOffset) range:range]; return attributedString; }
于是单行文本显示成这样:
![](http://upload-images.jianshu.io/upload_images/427885-d27f65102467fef4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
Label设置行间距_单行中文5间距偏移量.png
![](http://upload-images.jianshu.io/upload_images/427885-2162099ce77a9d96.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
Label设置行间距_单行英文5间距偏移量.png
那么多行呢?
![](http://upload-images.jianshu.io/upload_images/427885-8aacf6942c1a96f6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
Label设置行间距_多行中文5间距偏移量.png
![](http://upload-images.jianshu.io/upload_images/427885-c7a1e8d74c2cc211.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
Label设置行间距_多行英文5间距偏移量.png
我擦!
问题分析
通过上面的示例分析,可以简单的得到结论:未设置行间距和偏移量,什么问题都没有,只是行与行之间显示得比较紧促!
只设置行间距,多行和单行英文情况下,显示没有问题,但单行中文显示会有问题,底部会有空白!
既设置行间距,也设置偏移的情况下,单行显示没有问题,但多行显示有问题!
解决办法
多行情况下,不设置偏移!
那么问题来了,如何判断label显示几行呢?
笔者用比较笨的方法:计算某几个固定字符的高度,然后再计算label文本的高度,如果后者大于前者,则为多行!示例代码如下:
CGFloat lineSpace = 5; CGFloat offset = -(1.0/3 * lineSpace) - 1.0/3; CGFloat marginLeft = 20; CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineSpacing = lineSpace; // 调整行间距 NSDictionary *attrs = @{ NSFontAttributeName : self.lblResult.font, NSParagraphStyleAttributeName : paragraphStyle }; // 计算一行文本的高度 CGFloat oneHeight = [@"测试Test" boundingRectWithSize:CGSizeMake(screenWidth-marginLeft*2, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size.height; CGFloat rowHeight = [self.txtInputString.text boundingRectWithSize:CGSizeMake(screenWidth-marginLeft*2, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size.height; // 如果超出一行,则offset=0; offset = rowHeight > oneHeight ? 0 : offset; self.lblResult.attributedText = [self getAttributedStringWithString:self.txtInputString.text lineSpace:lineSpace baselineOffset:offset];
OK,这样貌似解决了上面的问题,但细心的你估计会发现一个问题:
CGFloat offset = -(1.0/3 * lineSpace) - 1.0/3;这行代码是什么意思?
关于 f(x) = -(1.0/3 * x) - 1.0/3
offset是通过穷举法归纳总结出来的,也许不够准确,但在项目中用起来挺好。根据文本内容,描点
// 描点 CGPoint points[15]; // CGPointMake(lineSpace, offset) points[0] = CGPointMake(5, -2); points[1] = CGPointMake(8, -3); points[2] = CGPointMake(10, -3.5); points[3] = CGPointMake(16, -6); points[4] = CGPointMake(20, -7); points[5] = CGPointMake(25, -9); points[6] = CGPointMake(30, -11); points[7] = CGPointMake(35, -11.5); points[8] = CGPointMake(40, -13); points[9] = CGPointMake(50, -15); points[10] = CGPointMake(60, -18.5); points[11] = CGPointMake(70, -23); points[12] = CGPointMake(80, -26); points[13] = CGPointMake(90, -29); points[14] = CGPointMake(100, -32); // 画线 [self drawLine:points count:15];
画线
// 画线 -(void)drawLine:(CGPoint[])points count:(NSInteger)count { CGMutablePathRef linePath = CGPathCreateMutable(); CGPathAddLines(linePath, NULL, points, count); // 关联layer和贝塞尔路径 self.linesLayer.path = linePath; CGPathRelease(linePath); // 创建Animation CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; animation.fromValue = @(0.0); animation.toValue = @(1.0); self.linesLayer.autoreverses = NO; animation.duration = 1.5f; // 设置layer的animation [self.linesLayer addAnimation:animation forKey:nil]; self.linesLayer.strokeEnd = 1; } ![Uploading Label设置行间距_归纳总结offset的算法_323780.png . . .]
![](http://upload-images.jianshu.io/upload_images/427885-106a802261250afd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/375)
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 讲解iOS开发中基本的定位功能实现
- iOS中定位当前位置坐标及转换为火星坐标的方法
- js判断客户端是iOS还是Android等移动终端的方法
- iOS应用开发中AFNetworking库的常用HTTP操作方法小结
- iOS应用中UISearchDisplayController搜索效果的用法
- iOS App开发中的UISegmentedControl分段组件用法总结
- IOS开发环境windows化攻略
- iOS应用中UITableView左滑自定义选项及批量删除的实现
- iOS中UIAlertView警告框组件的使用教程
- 浅析iOS应用开发中线程间的通信与线程安全问题
- iOS中的UIKeyboard键盘视图使用方法小结
- 检测iOS设备是否越狱的方法
- .net平台推送ios消息的实现方法