iOS 富文本之Label前后加文字“標(biāo)簽”

此篇是來記錄工程需求的玖翅。
先看需求圖吧



解析一下哮洽,title的文字換行,title前面加標(biāo)簽胁住,這樣的情況一般就會想到用NSMutableAttributedString富文本來解決五芝,富文本的圖文混排可以完美解決這個問題痘儡。但是,后臺帥哥哥告訴本寶寶了枢步,title前面的標(biāo)簽給返回的是文字沉删,并不是圖片……GG了……
富文本可以指定部分文字的背景顏色,但是要求的這個標(biāo)簽有背景醉途,也有圓角矾瑰,沒辦法解決了。只有View可以設(shè)置圓角隘擎,于是乎搜到了一個方法殴穴,把View轉(zhuǎn)化成Image的方法,然后就可以把一個Label轉(zhuǎn)化成一個Image货葬,恩完美解決采幌!
上代碼:

NSString *titleString = @"我是標(biāo)題!我是標(biāo)題震桶!我是標(biāo)休傍!我是標(biāo)題!";      
//創(chuàng)建  NSMutableAttributedString 富文本對象
NSMutableAttributedString *maTitleString = [[NSMutableAttributedString alloc] initWithString:titleString];
//創(chuàng)建一個小標(biāo)簽的Label
NSString *aa = @"我TM是個類似圖片的標(biāo)簽";
CGFloat aaW = 12*aa.length +6;
UILabel *aaL = [UILabel new];
aaL.frame = CGRectMake(0, 0, aaW*3, 16*3);
aaL.text = aa;
aaL.font = [UIFont boldSystemFontOfSize:12*3];
aaL.textColor = [UIColor whiteColor];
aaL.backgroundColor = [UIColor redColor];
aaL.clipsToBounds = YES;
aaL.layer.cornerRadius = 3*3;
aaL.textAlignment = NSTextAlignmentCenter;
//調(diào)用方法蹲姐,轉(zhuǎn)化成Image
UIImage *image = [self imageWithUIView:aaL];
//創(chuàng)建Image的富文本格式
NSTextAttachment *attach = [[NSTextAttachment alloc] init];
attach.bounds = CGRectMake(0, -2.5, aaW, 16); //這個-2.5是為了調(diào)整下標(biāo)簽跟文字的位置
attach.image = image;
//添加到富文本對象里
NSAttributedString * imageStr = [NSAttributedString attributedStringWithAttachment:attach];
[maTitleString insertAttributedString:imageStr atIndex:0];//加入文字前面
//[maTitleString appendAttributedString:imageStr];//加入文字后面
//[maTitleString insertAttributedString:imageStr atIndex:4];//加入文字第4的位置

//注意 :創(chuàng)建這個Label的時候磨取,frame人柿,font,cornerRadius要設(shè)置成所生成的圖片的3倍忙厌,也就是說要生成一個三倍圖凫岖,否則生成的圖片會虛,同學(xué)們可以試一試逢净。

//view轉(zhuǎn)成image
- (UIImage*) imageWithUIView:(UIView*) view{
    UIGraphicsBeginImageContext(view.bounds.size);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    [view.layer renderInContext:ctx];
    UIImage* tImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return tImage;
}

以上設(shè)置完畢哥放,然后加入你設(shè)置好的Label.text

UILabel *titleLabel = [UILabel new];
titleLabel.frame = CGRectMake(50, 200, 250, 100);
titleLabel.backgroundColor = [UIColor yellowColor];
titleLabel.numberOfLines = 0;
[self.view addSubview:titleLabel]; 
titleLabel.attributedText = maTitleString;
效果圖

2018年6月25日補充:
上面介紹了NSMutableAttributedString的基本設(shè)置,如果在大段大段的文字顯示的時候汹胃,就可能要求文字的行間距婶芭、縮進等類似Word的設(shè)置东臀,此時就要用到NSMutableParagraphStyle與NSParagraphStyle屬性着饥。
NSMutableParagraphStyle

    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.lineSpacing = 10; //字體的行間距
    paragraphStyle.lineHeightMultiple = 15; //字體行間距,默認(rèn)行與行之間為default個點的間距惰赋,如果小于0則無效宰掉,如果值大于0則在默認(rèn)值的基礎(chǔ)上再加上lineSpacing,文字之間總高度為即:(default + lineSpacing)赁濒,注意該間距不管字體大小
    paragraphStyle.firstLineHeadIndent = 20.0f; //首行縮進
    paragraphStyle.alignment = NSTextAlignmentJustified; //文本對齊方式(左轨奄,中,右拒炎,兩端對齊挪拟,自然)
    paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;//截斷模式,結(jié)尾部分的內(nèi)容以 ... 方式省略 ( "...wxyz" ,"abcd..." ,"ab...yz") --- 下面附枚舉
    paragraphStyle.headIndent = 20; //整體縮進(首行除外)击你,該值對應(yīng)屏幕上的點
    paragraphStyle.tailIndent = 20; //右側(cè)縮進或顯示寬度
    paragraphStyle.minimumLineHeight = 10; //最低行高
    paragraphStyle.maximumLineHeight = 20; //最大行高
    paragraphStyle.paragraphSpacing = 15; //段與段之間的間距
    paragraphStyle.paragraphSpacingBefore = 22.0f; //段首行空白空間
    paragraphStyle.baseWritingDirection = NSWritingDirectionLeftToRight; //從左到右的書寫方向(一共三種)
    paragraphStyle.hyphenationFactor = 1; //連字屬性 指定連字符門限玉组,有效值在0~1.0之間
    
//    paragraphStyle.tabStops //制表符
    //收縮字符間距允許截斷
    if (@available(iOS 9.0, *)) {
        paragraphStyle.allowsDefaultTighteningForTruncation = YES;
    } else {
        // Fallback on earlier versions
    }

//添加段落屬性
[maTitleString addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, maTitleString.length)];

此時Label的動態(tài)計算高度可以使用下面方法
-(CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(nullable NSDictionary<NSString *, id> *)attributes context:(nullable NSStringDrawingContext *)context NS_AVAILABLE(10_11, 7_0);

    UILabel *hLab = [[UILabel alloc]initWithFrame:CGRectMake(0, 64, 100, 100)];
    hLab.numberOfLines = 0;
    hLab.lineBreakMode = NSLineBreakByWordWrapping;
    hLab.text = @"三晉大地,生機盎然丁侄。\n6月21日至23日惯雳,***在山西省委書記駱惠寧、????省長樓陽生陪同下鸿摇,來到呂梁石景、忻州、太原等地拙吉,瞻仰革命紀(jì)念館潮孽、革命舊址,深入農(nóng)村筷黔、企業(yè)恩商,就當(dāng)前經(jīng)濟社會發(fā)展和貫徹落實黨的十八屆六中全會精神進行考察調(diào)研。";
    NSLog(@"=-=-%@",hLab.text);

    UIFont *font = [UIFont fontWithName:@"Arial" size:15.0f];
    CGSize size = CGSizeMake(self.view.frame.size.width, MAXFLOAT);
    NSRange allRange = [hLab.text rangeOfString:hLab.text];
    
    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc]init];
    style.lineSpacing = 10;//字體的行間距
    style.firstLineHeadIndent = 30.0f;//首行縮進
    
    NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:hLab.text];
    [attrStr addAttributes:@{NSFontAttributeName:font,NSForegroundColorAttributeName:[UIColor redColor],NSParagraphStyleAttributeName:style} range:allRange];

    CGRect rect = [attrStr boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading context:nil];
    hLab.frame = CGRectMake(10, 64, rect.size.width-20, rect.size.height);
    hLab.attributedText = attrStr;

附:NSParagraphStyle 的枚舉

typedef NS_ENUM(NSInteger, NSLineBreakMode) {
// Wrap at word boundaries, default
//出現(xiàn)在單詞邊界時起作用必逆,如果該單詞不在能在一行里顯示時怠堪,整體換行揽乱。此為段的默認(rèn)值
    NSLineBreakByWordWrapping = 0,      

// Wrap at character boundaries
//當(dāng)一行中最后一個位置的大小不能容納一個字符時,才進行換行粟矿。
    NSLineBreakByCharWrapping,      

// Simply clip 打斷不顯示....
//超出畫布邊緣部份將被截除凰棉。
    NSLineBreakByClipping,      

//截除前面部份,只保留后面一行的數(shù)據(jù)陌粹。前部份以...代替
// Truncate at head of line: "...wxyz"
    NSLineBreakByTruncatingHead,    

// Truncate at tail of line: "abcd..."
//截除后面部份撒犀,只保留前面一行的數(shù)據(jù),后部份以...代替掏秩。
    NSLineBreakByTruncatingTail,    

// Truncate middle of line:  "ab...yz"
//在一行中顯示段文字的前面和后面文字或舞,中間文字使用...代替。
    NSLineBreakByTruncatingMiddle   
} NS_ENUM_AVAILABLE(10_0, 6_0);

附:NSMutableAttributedString 屬性:

// NSFontAttributeName                設(shè)置字體屬性蒙幻,默認(rèn)值:字體:Helvetica(Neue) 字號:12  
// NSForegroundColorAttributeNam      設(shè)置字體顏色映凳,取值為 UIColor對象,默認(rèn)值為黑色  
// NSBackgroundColorAttributeName     設(shè)置字體所在區(qū)域背景顏色邮破,取值為 UIColor對象诈豌,默認(rèn)值為nil, 透明色  
// NSLigatureAttributeName            設(shè)置連體屬性,取值為NSNumber 對象(整數(shù))抒和,0 表示沒有連體字符矫渔,1 表示使用默認(rèn)的連體字符  
// NSKernAttributeName                設(shè)定字符間距,取值為 NSNumber 對象(整數(shù))摧莽,正值間距加寬庙洼,負(fù)值間距變窄  
// NSStrikethroughStyleAttributeName  設(shè)置刪除線,取值為 NSNumber 對象(整數(shù))  
// NSStrikethroughColorAttributeName  設(shè)置刪除線顏色镊辕,取值為 UIColor 對象油够,默認(rèn)值為黑色  
// NSUnderlineStyleAttributeName      設(shè)置下劃線,取值為 NSNumber 對象(整數(shù))丑蛤,枚舉常量 NSUnderlineStyle中的值叠聋,與刪除線類似  
// NSUnderlineColorAttributeName      設(shè)置下劃線顏色,取值為 UIColor 對象受裹,默認(rèn)值為黑色  
// NSStrokeWidthAttributeName         設(shè)置筆畫寬度碌补,取值為 NSNumber 對象(整數(shù)),負(fù)值填充效果棉饶,正值中空效果  
// NSStrokeColorAttributeName         填充部分顏色厦章,不是字體顏色,取值為 UIColor 對象  
// NSShadowAttributeName              設(shè)置陰影屬性照藻,取值為 NSShadow 對象  
// NSTextEffectAttributeName          設(shè)置文本特殊效果袜啃,取值為 NSString 對象,目前只有圖版印刷效果可用:  
// NSBaselineOffsetAttributeName      設(shè)置基線偏移值幸缕,取值為 NSNumber (float),正值上偏群发,負(fù)值下偏  
// NSObliquenessAttributeName         設(shè)置字形傾斜度晰韵,取值為 NSNumber (float),正值右傾,負(fù)值左傾  
// NSExpansionAttributeName           設(shè)置文本橫向拉伸屬性熟妓,取值為 NSNumber (float),正值橫向拉伸文本雪猪,負(fù)值橫向壓縮文本  
// NSWritingDirectionAttributeName    設(shè)置文字書寫方向,從左向右書寫或者從右向左書寫  
// NSVerticalGlyphFormAttributeName   設(shè)置文字排版方向起愈,取值為 NSNumber 對象(整數(shù))只恨,0 表示橫排文本,1 表示豎排文本  
// NSLinkAttributeName                設(shè)置鏈接屬性抬虽,點擊后調(diào)用瀏覽器打開指定URL地址  
// NSAttachmentAttributeName          設(shè)置文本附件,取值為NSTextAttachment對象,常用于文字圖片混排  
// NSParagraphStyleAttributeName      設(shè)置文本段落排版格式官觅,取值為 NSParagraphStyle 對象  

到這里已完成,有好的我建議歡迎同學(xué)來提喲~~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末阐污,一起剝皮案震驚了整個濱河市休涤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疤剑,老刑警劉巖滑绒,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件闷堡,死亡現(xiàn)場離奇詭異隘膘,居然都是意外死亡,警方通過查閱死者的電腦和手機杠览,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門弯菊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人踱阿,你說我怎么就攤上這事管钳。” “怎么了软舌?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵才漆,是天一觀的道長。 經(jīng)常有香客問我佛点,道長醇滥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任超营,我火速辦了婚禮鸳玩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘演闭。我一直安慰自己不跟,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布米碰。 她就那樣靜靜地躺著窝革,像睡著了一般购城。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上虐译,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天工猜,我揣著相機與錄音,去河邊找鬼菱蔬。 笑死篷帅,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拴泌。 我是一名探鬼主播魏身,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蚪腐!你這毒婦竟也來了箭昵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤回季,失蹤者是張志新(化名)和其女友劉穎家制,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體泡一,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡颤殴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鼻忠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涵但。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖帖蔓,靈堂內(nèi)的尸體忽然破棺而出矮瘟,到底是詐尸還是另有隱情,我是刑警寧澤塑娇,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布澈侠,位于F島的核電站,受9級特大地震影響埋酬,放射性物質(zhì)發(fā)生泄漏哨啃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一奇瘦、第九天 我趴在偏房一處隱蔽的房頂上張望棘催。 院中可真熱鬧,春花似錦耳标、人聲如沸醇坝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呼猪。三九已至画畅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宋距,已是汗流浹背轴踱。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谚赎,地道東北人淫僻。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像壶唤,于是被迫代替她去往敵國和親雳灵。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353