本文說明了如何在創(chuàng)建UILabel時(shí)讓標(biāo)簽的寬度根據(jù)文字內(nèi)容長(zhǎng)度而自適應(yīng),即標(biāo)簽寬度動(dòng)態(tài)變化
在實(shí)際開發(fā)中,我們可能會(huì)需要在創(chuàng)建完一個(gè)UILabel對(duì)象后的使用過程中,隨時(shí)改變標(biāo)簽的文字內(nèi)容,比如頁面刷新的提示,可能出現(xiàn)的文字比如:
- “下拉加載”
- “正在刷新,請(qǐng)稍候”
- “網(wǎng)絡(luò)異常,請(qǐng)檢查網(wǎng)絡(luò)并稍后再試!”
這種情況我們一般不會(huì)創(chuàng)建多個(gè)標(biāo)簽并通過顯示和隱藏來展示,我們希望用一個(gè)標(biāo)簽來動(dòng)態(tài)展示不同的文字,這個(gè)時(shí)候如果標(biāo)簽有背景顏色或者背景圖片時(shí),就要照顧最長(zhǎng)的文字內(nèi)容來設(shè)定寬度,這樣在展示較短文字時(shí),標(biāo)簽背景會(huì)顯得很空曠,在制作toast時(shí)可能會(huì)更加明顯,為了隨時(shí)根據(jù)文字內(nèi)容變換寬度,我們可以參考以下步驟:
- 我們通過創(chuàng)建一個(gè)新的類繼承自UILabel來自動(dòng)完成自適應(yīng)寬度的功能,這個(gè)類的頭文件只需要聲明幾個(gè)方法即可:
//MPLabel.h
#import <UIKit/UIKit.h>
@interface MPLabel : UILabel
//允許通過原點(diǎn)來控制標(biāo)簽位置,參數(shù)分別為:原點(diǎn)坐標(biāo)、文字內(nèi)容、文字字體、空白邊界(后面會(huì)提到)
- (void)setLabelWithOrigin:(CGPoint)origin mutableText:(NSString *)text mutableFont:(UIFont *)font margin:(CGFloat)margin;
//允許通過中心點(diǎn)來控制標(biāo)簽位置,參數(shù)分別為:原點(diǎn)坐標(biāo)、文字內(nèi)容、文字字體、空白邊界(后面會(huì)提到)
- (void)setLabelWithCenter:(CGPoint)center mutableText:(NSString *)text mutableFont:(UIFont *)font margin:(CGFloat)margin;
@end
這里我們提供的方法可以讓用戶根據(jù)需要,通過原點(diǎn)或者中心點(diǎn)來確定要繪制的標(biāo)簽的位置,至于標(biāo)簽的高度則是由字號(hào)來決定的,標(biāo)簽的寬度是由字號(hào)和文字內(nèi)容長(zhǎng)短共同決定的,注意我們通過這個(gè)方法繪制的標(biāo)簽,在首尾兩端會(huì)是緊貼在文字兩端的,如果我們希望跟讓文字和背景在首尾兩端有一定量的空隙,可以設(shè)置margin這個(gè)參數(shù),后面會(huì)看到這個(gè)參數(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è)置,后面的方法會(huì)重新設(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è),也可以再添加一個(gè)新的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í),都可以滿足啟動(dòng)條件,這里我們先預(yù)設(shè)一個(gè)后面會(huì)被重新根據(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上展示即可,下面舉幾個(gè)例子:
- (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測(cè)試\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í)不同的空白邊界也能通過對(duì)比看出來
如果是同一個(gè)標(biāo)簽要?jiǎng)討B(tài)改變其屬性,只需要在要改變的時(shí)候調(diào)用上述方法即可立即更新,比如按鈕的點(diǎn)擊事件等