内容摘要

  • UILabel显示多行文本
  • UILabel设置行间距
  • 解决单行文本 & 多行文本显示的问题

场景描述

  • 众所周知,UILabel显示多行的话,默认行间距为0,但实际开发中,如果显示多行文本,一般情况下会有一定的行间距。如果想动态调整行间距,则需要赋值富文本属性(而不是文本属性

问题分析

Label显示多行文本

  • label默认情况下,只会显示单行文本,主要是因为它的numberOfLines属性值是1;如果要显示多行,把这个属性值改成0即可。
self.lblResult.numberOfLines = 0;
  • 默认情况下,会显示成这样: 
  • 如果想添加行间距,你可能会这样做:

  • 写一个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];
  • 结果如下图: 
     
    =============== 华丽的分割线 ===============

    问题:以上方法显示多行文本貌似没有问题,但如果文本只有一行呢?

Label显示单行文本

  • 显示单行中文:
NSString *string = @"文本只有一行会显示什么样?";
self.lblResult.attributedText = [self getAttributedStringWithString:string lineSpace:5];

  • 显示单行英文:
NSString *string = @"good good study day day up";
self.lblResult.attributedText = [self getAttributedStringWithString:string lineSpace:5];

  • 通过比较发现,用同样的方法,单行显示中文 & 英文,效果不同,中文会多了一些空白!心中立马有种蛋蛋的忧桑,一丝丝凄凉……

遇到问题之后

  • 查询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
    • 1
    • 1

尝试解决问题

  • 重构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;
}
  • 于是单行文本显示成这样: 
     

  • 那么多行呢? 
     

我擦!

问题分析

  • 通过上面的示例分析,可以简单的得到结论:

    • 未设置行间距和偏移量,什么问题都没有,只是行与行之间显示得比较紧促!
    • 只设置行间距,多行和单行英文情况下,显示没有问题,但单行中文显示会有问题,底部会有空白!
    • 既设置行间距,也设置偏移的情况下,单行显示没有问题,但多行显示有问题!

解决办法

  • 多行情况下,不设置偏移!

那么问题来了,如何判断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://blog.csdn.net/chenyblog/article/details/51172776  是原文地址   感谢分享 

Label设置行间距--b的更多相关文章

  1. Label设置行间距

    内容摘要 UILabel显示多行文本 UILabel设置行间距 解决单行文本 & 多行文本显示的问题 场景描述 众所周知,UILabel显示多行的话,默认行间距为0,但实际开发中,如果显示多行 ...

  2. 设置textView或者label的行间距方法

    一,效果图. 二,代码. RootViewController.m - (void)viewDidLoad { [super viewDidLoad]; // Do any additional se ...

  3. 【代码笔记】iOS-设置textView或者label的行间距方法

    一,效果图. 二,代码. RootViewController.m - (void)viewDidLoad { [super viewDidLoad]; // Do any additional se ...

  4. UILabel设置行间距和字间距并计算高度-b

    #define UILABEL_LINE_SPACE 6 #define HEIGHT [ [ UIScreen mainScreen ] bounds ].size.height //给UILabe ...

  5. QLabel设置行间距(使用html的语法,比较巧妙)

    1.设置行间距 QLabel没有设置行间距的函数,所以这种办法是行不通的.只能采用其它类似的方法来实现,例如设置行高,使用样式代码如下: <p style='line-height:18px'& ...

  6. iOS UILabel设置行间距和字间距

    实现UILabel的文字,设置行间距和字间距. 效果图: 代码: let lblTitle = UILabel(frame: CGRect(x: , y: , width: KScreenWidth- ...

  7. 使用CSS设置行间距,字间距.

    字间距1.text-indent设置抬头距离css缩进即对,对应div设置css样式text-indent : 20px; 缩进了20px 2.letter-spacing来设置字与字间距_字符间距离 ...

  8. C# 、winform 添加皮肤后(IrisSkin2) label设置的颜色 无法显示

    C# .winform 添加皮肤后(IrisSkin2) label设置的颜色 无法显示 解决方法一:设置label的Tag属性值与skinEngine的DisableTag属性值相同即可.默认值是9 ...

  9. C# RichTextBox设置行间距

    之前从CSDN上下载了一个代码,参看之后,改了一些内容,感觉设置行间距更具体,不会因为字号的变化而受到影响,具体代码参看: CSDN:http://download.csdn.net/detail/n ...

随机推荐

  1. [Node] 逃离回调地狱

    逃离Node回调地狱 Background : 在Node中,函数的返回结果大多利用回调的方式处理.如简单的判断文件是否存在并读取内容: var fs = require('fs'); fs.exis ...

  2. iOS 视频播放的简单使用

    最近工作中有用到视频播放的内容,分享一些简单的用法给大家(由于网速问题,本例中使用的是本地的资源进行播放,要播放网络上的修改一些URL即可) 1.iOS9之前的视频播放 首先需要导入MediaPlay ...

  3. 【JAVA - SSM】之MyBatis插入数据后获取自增主键

    很多时候,我们都需要在插入一条数据后回过头来获取到这条数据在数据表中的自增主键,便于后续操作.针对这个问题,有两种解决方案: (1)先插入,后查询.我们可以先插入一条数据,然后根据插入的数据的各个字段 ...

  4. java 图片压缩 剪切 水印 转换 黑白 缩放

    专注java已6年,欢迎加入java核心技术QQ群:135138817,每周五晚有群主进行技术讲座. import java.awt.AlphaComposite; import java.awt.C ...

  5. Linux 性能优化之 IO 子系统 系列 图

    http://blog.sina.com.cn/s/articlelist_1029388674_11_1.html Linux 性能优化之 IO 子系统(一) 本文介绍了对 Linux IO 子系统 ...

  6. bash手册 之重定向原理与实现

    http://www.gnu.org/software/bash/manual/bashref.html#Redirections http://www.cnblogs.com/weidagang20 ...

  7. Linux shell的&&和||--转载

    Linux shell的&&和||   shell 在执行某个命令的时候,会返回一个返回值,该返回值保存在 shell 变量 $? 中.当 $? == 0 时,表示执行成功:当 $? ...

  8. [Eclipse]The type XXX cannot be resolved. It is indirectly referenced from required .class files

    在Eclipse中遇到The type XXX cannot be resolved. It is indirectly referenced from required .class files错误 ...

  9. PHP 基础语法 常量 变量

    PHP基础语法 标记 当解析一个文件时,PHP 会寻找起始和结束标记,也就是 <?php 和 ?>,这告诉 PHP 开始和停止解析二者之间的代码.此种解析方式使得 PHP 可以被嵌入到各种 ...

  10. oracle编译 失效对象方式

    如果procedure 所使用的表结构发生了改变等其它情况,在相应的xxx_objects表的status字段会变为invalid状态,但是如果在调用时procedure会自动编译,grant失效对象 ...