【iOS開發(fā)UI篇】UILabel根據(jù)文字內(nèi)容自適應(yīng)寬度

本文說明了如何在創(chuàng)建UILabel時(shí)讓標(biāo)簽的寬度根據(jù)文字內(nèi)容長度而自適應(yīng)爷抓,即標(biāo)簽寬度動態(tài)變化

在實(shí)際開發(fā)中,我們可能會需要在創(chuàng)建完一個UILabel對象后的使用過程中磕秤,隨時(shí)改變標(biāo)簽的文字內(nèi)容脐湾,比如頁面刷新的提示臭笆,可能出現(xiàn)的文字比如:

  • “下拉加載”
  • “正在刷新,請稍候”
  • “網(wǎng)絡(luò)異常,請檢查網(wǎng)絡(luò)并稍后再試愁铺!”

這種情況我們一般不會創(chuàng)建多個標(biāo)簽并通過顯示和隱藏來展示鹰霍,我們希望用一個標(biāo)簽來動態(tài)展示不同的文字,這個時(shí)候如果標(biāo)簽有背景顏色或者背景圖片時(shí)茵乱,就要照顧最長的文字內(nèi)容來設(shè)定寬度茂洒,這樣在展示較短文字時(shí),標(biāo)簽背景會顯得很空曠瓶竭,在制作toast時(shí)可能會更加明顯督勺,為了隨時(shí)根據(jù)文字內(nèi)容變換寬度,我們可以參考以下步驟:

  • 我們通過創(chuàng)建一個新的類繼承自UILabel來自動完成自適應(yīng)寬度的功能斤贰,這個類的頭文件只需要聲明幾個方法即可:
//MPLabel.h

#import <UIKit/UIKit.h>

@interface MPLabel : UILabel

//允許通過原點(diǎn)來控制標(biāo)簽位置智哀,參數(shù)分別為:原點(diǎn)坐標(biāo)、文字內(nèi)容荧恍、文字字體瓷叫、空白邊界(后面會提到)
- (void)setLabelWithOrigin:(CGPoint)origin mutableText:(NSString *)text mutableFont:(UIFont *)font margin:(CGFloat)margin;

//允許通過中心點(diǎn)來控制標(biāo)簽位置,參數(shù)分別為:原點(diǎn)坐標(biāo)送巡、文字內(nèi)容摹菠、文字字體、空白邊界(后面會提到)
- (void)setLabelWithCenter:(CGPoint)center mutableText:(NSString *)text mutableFont:(UIFont *)font margin:(CGFloat)margin;

@end

這里我們提供的方法可以讓用戶根據(jù)需要骗爆,通過原點(diǎn)或者中心點(diǎn)來確定要繪制的標(biāo)簽的位置次氨,至于標(biāo)簽的高度則是由字號來決定的,標(biāo)簽的寬度是由字號和文字內(nèi)容長短共同決定的淮腾,注意我們通過這個方法繪制的標(biāo)簽糟需,在首尾兩端會是緊貼在文字兩端的屉佳,如果我們希望跟讓文字和背景在首尾兩端有一定量的空隙谷朝,可以設(shè)置margin這個參數(shù),后面會看到這個參數(shù)是直接加載標(biāo)簽寬度上的

  • 接下來就是.m文件了武花,和之前繪制變色文字標(biāo)簽不同圆凰,我們不需要重寫drawRect方法
//MPLabel.m

#import "MPLabel.h"

@interface MPLabel()

{
    CGPoint _origin;    //原點(diǎn)
    CGPoint _center;    //中心點(diǎn)
    CGFloat _margin;    //空白邊界
    int initPoint;      //判斷標(biāo)志,判斷當(dāng)前frame根據(jù)那種規(guī)則設(shè)定
    NSMutableString *_mutableText;  //標(biāo)簽文字內(nèi)容
    UIFont *_mutableFont;           //標(biāo)簽文字字體
}

@end

@implementation MPLabel

- (instancetype)init {
    
    if (self = [super init]) {
        self.frame = CGRectMake(10, 10, 10, 10); //預(yù)設(shè)体箕,可隨意設(shè)置专钉,后面的方法會重新設(shè)置
        self.numberOfLines = 0;
        self.textAlignment = NSTextAlignmentCenter;
    }
    return self;
}

- (void)awakeFromNib {
    
    self.frame = CGRectMake(10, 10, 10, 10);
    self.numberOfLines = 0;
    self.textAlignment = NSTextAlignmentCenter;
    
    [super awakeFromNib];
}

- (void)setLabelWithOrigin:(CGPoint)origin mutableText:(NSString *)text mutableFont:(UIFont *)font margin:(CGFloat)margin {
    
    initPoint = 1; //1表示設(shè)定了原點(diǎn)
    
    _origin = origin;
    _margin = margin > 0 ? margin : 0;
    _mutableText = [text mutableCopy];
    _mutableFont = font;
    
    [self setTitle];
}

- (void)setLabelWithCenter:(CGPoint)center mutableText:(NSString *)text mutableFont:(UIFont *)font margin:(CGFloat)margin {
    
    initPoint = 2; //2表示設(shè)定了中心點(diǎn)
    
    _center = center;
    _margin = margin > 0 ? margin : 0;
    _mutableText = [text mutableCopy];
    _mutableFont = font;
    
    [self setTitle];
}

- (void)setTitle {
    
    NSDictionary *textAttributes;
    
    textAttributes = @{NSFontAttributeName:_mutableFont};
    
    CGSize textSize = [_mutableText sizeWithAttributes:textAttributes];
    
    //這里的margin加在了寬度兩側(cè),如果要做豎排標(biāo)簽累铅,可以選擇加在高度兩側(cè)跃须,也可以再添加一個新的margin參數(shù)來同時(shí)控制寬度和高度上的空白邊界
    if (initPoint == 1) {
        self.frame = CGRectMake(_origin.x, _origin.y, textSize.width + 2*_margin, textSize.height);
    } else if (initPoint == 2) {
        self.center = _center;
        self.bounds = CGRectMake(0, 0, textSize.width + 2*_margin, textSize.height);
    }
    
    [self setText:_mutableText];
    [self setFont:_mutableFont];
}

@end

這里重寫init和awakeFromNib方法是為了在使用代碼創(chuàng)建控件或使用xib創(chuàng)建控件時(shí),都可以滿足啟動條件娃兽,這里我們先預(yù)設(shè)一個后面會被重新根據(jù)文字內(nèi)容設(shè)置寬度的frame菇民,然后把標(biāo)簽設(shè)置成可以換行和文字居中就可以了

在暴露的接口中,我們只需要將參數(shù)都保存下來就可以了,接著調(diào)用setTitle來進(jìn)行最重要的工作第练,我們首先將字體參數(shù)保存成為屬性字典阔馋,接下來使用sizeWithAttributes方法來獲取該字符串在該屬性下得尺寸(網(wǎng)絡(luò)上多數(shù)使用了舊版本的sizeWithFont方法,通過查閱文檔可以知道該方法已被替換)娇掏,最后再根據(jù)已有的參數(shù)來設(shè)置標(biāo)簽最終的尺寸呕寝、文字內(nèi)容和文字字體

  • 最后我們只需要在需要添加標(biāo)簽的地方創(chuàng)建標(biāo)簽(代碼或xib),然后調(diào)用頭文件中的任意方法(也可以根據(jù)需要添加其他方法)來完成設(shè)置婴梧,最終添加到superview上展示即可下梢,下面舉幾個例子:
- (void)viewDidLoad {
    [super viewDidLoad];

    MPLabel *testLabel1 = [[MPLabel alloc] init];
    [testLabel1 setLabelWithCenter:CGPointMake(200, 50) mutableText:@"This is a piece of test code!" mutableFont:[UIFont boldSystemFontOfSize:20] margin:0];
    testLabel1.backgroundColor = [UIColor yellowColor];
    testLabel1.textColor = [UIColor redColor];
    [self.view addSubview:testLabel1];
    
    MPLabel *testLabel2 = [[MPLabel alloc] init];
    [testLabel2 setLabelWithCenter:CGPointMake(200, 150) mutableText:@"#\n測試\n標(biāo)簽\n#" mutableFont:[UIFont systemFontOfSize:35] margin:10];
    testLabel2.backgroundColor = [UIColor blueColor];
    testLabel2.textColor = [UIColor whiteColor];
    [self.view addSubview:testLabel2];
    
    MPLabel *testLabel3 = [[MPLabel alloc] init];
    [testLabel3 setLabelWithOrigin:CGPointMake(200, 250) mutableText:@"!!!!!!!!!!!!!!!!" mutableFont:[UIFont systemFontOfSize:50] margin:20];
    testLabel3.backgroundColor = [UIColor greenColor];
    testLabel3.textColor = [UIColor brownColor];
    [self.view addSubview:testLabel3];
自適應(yīng)寬度標(biāo)簽

這里可以看到這樣的自適應(yīng)適用于橫向或縱向的標(biāo)簽,同時(shí)不同的空白邊界也能通過對比看出來

如果是同一個標(biāo)簽要動態(tài)改變其屬性志秃,只需要在要改變的時(shí)候調(diào)用上述方法即可立即更新怔球,比如按鈕的點(diǎn)擊事件等

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市浮还,隨后出現(xiàn)的幾起案子竟坛,更是在濱河造成了極大的恐慌,老刑警劉巖钧舌,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件担汤,死亡現(xiàn)場離奇詭異,居然都是意外死亡洼冻,警方通過查閱死者的電腦和手機(jī)崭歧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來撞牢,“玉大人率碾,你說我怎么就攤上這事∥荼耄” “怎么了所宰?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長畜挥。 經(jīng)常有香客問我仔粥,道長,這世上最難降的妖魔是什么蟹但? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任躯泰,我火速辦了婚禮,結(jié)果婚禮上华糖,老公的妹妹穿的比我還像新娘麦向。我一直安慰自己,他們只是感情好客叉,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布诵竭。 她就那樣靜靜地躺著景描,像睡著了一般。 火紅的嫁衣襯著肌膚如雪秀撇。 梳的紋絲不亂的頭發(fā)上超棺,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機(jī)與錄音呵燕,去河邊找鬼棠绘。 笑死,一個胖子當(dāng)著我的面吹牛再扭,可吹牛的內(nèi)容都是我干的氧苍。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼泛范,長吁一口氣:“原來是場噩夢啊……” “哼让虐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起罢荡,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤赡突,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后区赵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惭缰,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年笼才,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了漱受。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡骡送,死狀恐怖昂羡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情摔踱,我是刑警寧澤虐先,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站昌渤,受9級特大地震影響赴穗,放射性物質(zhì)發(fā)生泄漏憔四。R本人自食惡果不足惜膀息,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望了赵。 院中可真熱鬧潜支,春花似錦、人聲如沸柿汛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至裁替,卻和暖如春项玛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背弱判。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工襟沮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人昌腰。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓开伏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親遭商。 傳聞我的和親對象是個殘疾皇子固灵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345

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