Label设置行间距

Label设置行间距

内容摘要

  • UILabel突显多行文本
  • UILabel设置行间距
  • 赶尽杀绝单行文本 & 多行文本展现的标题

此情此景描述

  • 同理可得,UILabel呈现多行的话,暗中认可行间距为0,但骨子里开发中,如若彰显多行文本,一般意况下会有早晚的行间距。假如想动态调整行间距,则要求赋值富文本属性(而不是文本属性

难题分析

Label突显多行文本

  • label暗中认可景况下,只会来得单行文本,首如果因为它的numberOfLines属性值是1;假如要突显多行,把那个属性值改成0即可。

self.lblResult.numberOfLines = 0;
  • 私下认可意况下,会来得成那样:
Label设置行间距\_多行0间距.png
  • 假定想添加行间距,你只怕会如此做:

    • 写2个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;
    

}
* 赋值富文本属性 objc
NSString string =
@”威名昭著,UILabel突显多行的话,暗中同意行间距为0,但实则付出中,假设呈现多行文本,一般景况下会有早晚的行间距。假使想动态调整行间距,则需求赋值富文本属性
*(而不是文本属性)”;
// 5:行间距
self.lblResult.attributedText = [self
getAttributedStringWithString:string lineSpace:5];
“`

  • 结果如下图:
Label设置行间距\_多行5间距.png



=============== 华丽的分割线 ===============  
</br>

难点:以上办法呈现多创作本貌似没有毛病,但若是文本唯有一行呢?

Label彰显单行文本

  • 来得单行中文:

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

Label设置行间距_单行汉语5间距.png

  • 显示单行英文:

NSString *string = @"good good study day day up";
self.lblResult.attributedText = [self getAttributedStringWithString:string lineSpace:5];

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;
}
  • 于是单行文本呈现成这么:
Label设置行间距\_单行中文5间距偏移量.png



Label设置行间距\_单行英文5间距偏移量.png
  • 这便是说多行吧?
Label设置行间距\_多行中文5间距偏移量.png



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 . . .]

Label设置行间距_归咎总括offset的算法.png

相关文章