本文說明了如何在創(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)簽,同時(shí)不同的空白邊界也能通過對比看出來
如果是同一個標(biāo)簽要動態(tài)改變其屬性志秃,只需要在要改變的時(shí)候調(diào)用上述方法即可立即更新怔球,比如按鈕的點(diǎn)擊事件等