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

本文說明了如何在創(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)簽

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容