Label設(shè)置行間距

Label設(shè)置行間距

內(nèi)容摘要

  • UILabel顯示多行文本
  • UILabel設(shè)置行間距
  • 解決單行文本 & 多行文本顯示的問題

場景描述

  • 眾所周知球化,UILabel顯示多行的話,默認(rèn)行間距為0蛔趴,但實際開發(fā)中,如果顯示多行文本,一般情況下會有一定的行間距谢揪。如果想動態(tài)調(diào)整行間距,則需要賦值富文本屬性(而不是文本屬性

問題分析

Label顯示多行文本

  • label默認(rèn)情況下捐凭,只會顯示單行文本拨扶,主要是因為它的numberOfLines屬性值是1;如果要顯示多行茁肠,把這個屬性值改成0即可患民。
self.lblResult.numberOfLines = 0;
  • 默認(rèn)情況下,會顯示成這樣:


    Label設(shè)置行間距_多行0間距.png
  • 如果想添加行間距垦梆,你可能會這樣做:
    • 寫一個string轉(zhuǎn)換成AttributedString的方法(或者給字符串增加一個分類)
    -(NSAttributedString *)getAttributedStringWithString:(NSString *)string lineSpace:(CGFloat)lineSpace {
        NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string];
        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
        paragraphStyle.lineSpacing = lineSpace; // 調(diào)整行間距
        NSRange range = NSMakeRange(0, [string length]);
        [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range];
        return attributedString;
    

}
* 賦值富文本屬性 objc
NSString string = @"眾所周知匹颤,UILabel顯示多行的話,默認(rèn)行間距為0托猩,但實際開發(fā)中印蓖,如果顯示多行文本,一般情況下會有一定的行間距京腥。如果想動態(tài)調(diào)整行間距另伍,則需要賦值富文本屬性*(而不是文本屬性)";
// 5:行間距
self.lblResult.attributedText = [self getAttributedStringWithString:string lineSpace:5];
```

  • 結(jié)果如下圖:


    Label設(shè)置行間距_多行5間距.png

    =============== 華麗的分割線 ===============
    </br>

問題:以上方法顯示多行文本貌似沒有問題,但如果文本只有一行呢?

Label顯示單行文本

  • 顯示單行中文:
NSString *string = @"文本只有一行會顯示什么樣摆尝?";
self.lblResult.attributedText = [self getAttributedStringWithString:string lineSpace:5];
Label設(shè)置行間距_單行中文5間距.png
  • 顯示單行英文:
NSString *string = @"good good study day day up";
self.lblResult.attributedText = [self getAttributedStringWithString:string lineSpace:5];
Label設(shè)置行間距_單行英文5間距1.png
  • 通過比較發(fā)現(xiàn)温艇,用同樣的方法,單行顯示中文 & 英文堕汞,效果不同勺爱,中文會多了一些空白!心中立馬有種蛋蛋的憂桑讯检,一絲絲凄涼……

遇到問題之后

  • 查詢API-NSMutableParagraphStyle

// Indent:縮進(jìn)
@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
    

嘗試解決問題

  • 重構(gòu)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; // 調(diào)整行間距
    NSRange range = NSMakeRange(0, [string length]);
    [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range];
    // 設(shè)置文本偏移量
    [attributedString addAttribute:NSBaselineOffsetAttributeName value:@(baselineOffset) range:range];
    return attributedString;
}
  • 于是單行文本顯示成這樣:


    Label設(shè)置行間距_單行中文5間距偏移量.png

    Label設(shè)置行間距_單行英文5間距偏移量.png
  • 那么多行呢人灼?


    Label設(shè)置行間距_多行中文5間距偏移量.png

    Label設(shè)置行間距_多行英文5間距偏移量.png

    我擦围段!

問題分析

  • 通過上面的示例分析,可以簡單的得到結(jié)論:
    • 未設(shè)置行間距和偏移量投放,什么問題都沒有奈泪,只是行與行之間顯示得比較緊促!
    • 只設(shè)置行間距灸芳,多行和單行英文情況下涝桅,顯示沒有問題,但單行中文顯示會有問題烙样,底部會有空白冯遂!
    • 既設(shè)置行間距,也設(shè)置偏移的情況下谒获,單行顯示沒有問題蛤肌,但多行顯示有問題!

解決辦法

  • 多行情況下批狱,不設(shè)置偏移裸准!

那么問題來了,如何判斷l(xiāng)abel顯示幾行呢精耐?

  • 筆者用比較笨的方法:計算某幾個固定字符的高度狼速,然后再計算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; // 調(diào)整行間距
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恼蓬,這樣貌似解決了上面的問題惊完,但細(xì)心的你估計會發(fā)現(xiàn)一個問題:CGFloat offset = -(1.0/3 * lineSpace) - 1.0/3;這行代碼是什么意思?

關(guān)于 f(x) = -(1.0/3 * x) - 1.0/3

  • offset是通過窮舉法歸納總結(jié)出來的处硬,也許不夠準(zhǔn)確小槐,但在項目中用起來挺好。
  • 根據(jù)文本內(nèi)容,描點
// 描點
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);
    // 關(guān)聯(lián)layer和貝塞爾路徑
    self.linesLayer.path = linePath;
    CGPathRelease(linePath);
    // 創(chuàng)建Animation
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    animation.fromValue = @(0.0);
    animation.toValue = @(1.0);
    self.linesLayer.autoreverses = NO;
    animation.duration = 1.5f;
    // 設(shè)置layer的animation
    [self.linesLayer addAnimation:animation forKey:nil];
    self.linesLayer.strokeEnd = 1;
}
![Uploading Label設(shè)置行間距_歸納總結(jié)offset的算法_323780.png . . .]
Label設(shè)置行間距_歸納總結(jié)offset的算法.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末凿跳,一起剝皮案震驚了整個濱河市件豌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌控嗜,老刑警劉巖茧彤,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異疆栏,居然都是意外死亡曾掂,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門壁顶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來珠洗,“玉大人,你說我怎么就攤上這事若专⌒肀停” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵富岳,是天一觀的道長蛔糯。 經(jīng)常有香客問我,道長窖式,這世上最難降的妖魔是什么蚁飒? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮萝喘,結(jié)果婚禮上淮逻,老公的妹妹穿的比我還像新娘。我一直安慰自己阁簸,他們只是感情好爬早,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著启妹,像睡著了一般筛严。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上饶米,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天桨啃,我揣著相機(jī)與錄音,去河邊找鬼檬输。 笑死照瘾,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丧慈。 我是一名探鬼主播析命,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鹃愤?” 一聲冷哼從身側(cè)響起簇搅,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎软吐,沒想到半個月后馍资,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡关噪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年鸟蟹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片使兔。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡建钥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出虐沥,到底是詐尸還是另有隱情熊经,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布欲险,位于F島的核電站镐依,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏天试。R本人自食惡果不足惜槐壳,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望喜每。 院中可真熱鬧务唐,春花似錦、人聲如沸带兜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽刚照。三九已至刑巧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間无畔,已是汗流浹背啊楚。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留檩互,地道東北人特幔。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓咨演,卻偏偏與公主長得像闸昨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容