天天看點

使用NSMutableAttributedString添加下劃線、删除線、陰影、填充、不同字型顔色等

在iOS開發中,有時會遇到需要添加下劃線,或者設定字元串中某幾個字的顔色的情況,最常見的栗子就是注冊頁面,如圖所示:

使用NSMutableAttributedString添加下劃線、删除線、陰影、填充、不同字型顔色等

幾乎所有注冊頁面中都會出現這麼一句話 “點選下一步表示您已同意《使用者服務協定》”,而且可以看到,“《使用者服務協定》”幾個字是橙色的,并且它們下面還有下劃線。這是怎麼實作的呢?

有的同學可能會說:“不同顔色就設定兩個label,讓左邊的label顯示前半句并設定為黑色,讓右邊的label顯示後半句并設定為橙色就行了。” 這樣也許是一個辦法,但是感覺有些麻煩,而且如果有很多種顔色呢?難道要設定一大堆label嗎。。。

NSMutableAttributedString 就可以完美的解決這些問題。我們先說一下和 attributes 有關的四個方法:

為某一範圍内文字設定多個屬性

- (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range;

為某一範圍内文字添加某個屬性

- (void)addAttribute:(NSString *)name value:(id)value range:(NSRange)range;

為某一範圍内文字添加多個屬性

- (void)addAttributes:(NSDictionary *)attrs range:(NSRange)range;

移除某一範圍内的某個屬性

- (void)removeAttribute:(NSString *)name range:(NSRange)range;

我們來舉個栗子吧:

- (void)viewDidLoad {
    [super viewDidLoad];

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, ScreenWidth, 40)];
    label.font = [UIFont systemFontOfSize:18]; // 字型大小
    label.textAlignment = NSTextAlignmentCenter; // 文字對齊方式
    
    NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:
        @"點選下一步表示您已同意《使用者服務協定》"];
    [str addAttribute:NSForegroundColorAttributeName value:
        [UIColor colorWithRed:100/255.0 green:100/255.0 blue:100/255.0 alpha:1] range:NSMakeRange(0,11)];
    [str addAttribute:NSForegroundColorAttributeName value:
        [UIColor colorWithRed:255/255.0 green:110/255.0 blue:17/255.0 alpha:1] range:NSMakeRange(11,8)];

    label.attributedText = str;
    [self.view addSubview:label];
}
           

我們建立一個 NSMutableAttributedString 的對象 str,然後為它添加一個屬性,這個屬性的名字叫做 NSForegroundColorAttributeName,就是文字的顔色,它的值是 UIColor 類型的,預設是黑色,我們給它自定義一個顔色。然後我們來設定它的範圍,NSMakeRange(0, 11) 的意思就是說,從第0個字開始,一共11個字。這個範圍其實就是 “點選下一步表示您已同意” 這11個字。(事實上,第一幅圖中的這11個字并不是黑色,但是和黑色比較接近,這不重要~)

然後我們又給這個字元串添加了一個屬性,這個屬性還是 NSForegroundColorAttributedName,但是顔色是橙色,并且範圍是從第11(别忘了編号從0開始)個字開始,一共8個字。這個範圍其實就是 “《使用者服務協定》“(書名号也算)

現在我們運作程式來看看效果:

使用NSMutableAttributedString添加下劃線、删除線、陰影、填充、不同字型顔色等

文字顔色已經搞定了,接下來我們來加下劃線。我們在原來代碼的基礎上再加一句話:

- (void)viewDidLoad {
    [super viewDidLoad];

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, ScreenWidth, 40)];
    label.font = [UIFont systemFontOfSize:18]; // 字型大小
    label.textAlignment = NSTextAlignmentCenter; // 文字對齊方式
    
    NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:
        @"點選下一步表示您已同意《使用者服務協定》"];
    [str addAttribute:NSForegroundColorAttributeName value:
        [UIColor colorWithRed:100/255.0 green:100/255.0 blue:100/255.0 alpha:1] range:NSMakeRange(0,11)];
    [str addAttribute:NSForegroundColorAttributeName value:
        [UIColor colorWithRed:255/255.0 green:110/255.0 blue:17/255.0 alpha:1] range:NSMakeRange(11,8)];
    [str addAttribute:NSUnderlineStyleAttributeName value:
        [NSNumber numberWithInteger:NSUnderlineStyleSingle] range:NSMakeRange(12, 6)]; // 下劃線
    
    label.attributedText = str;
    [self.view addSubview:label];
}
           

這句話的意思就是說,給 str 添加一個屬性,這個屬性的名字是 NSUnderlineStyleAttributeName,也就是下劃線的類型。它的值是 NSInteger 類型的,預設是0,也就是沒有下劃線。範圍是從第12個字開始,一共6個字。也就是 “使用者服務條款”。

這裡要注意。我們再來看一遍添加屬性的方法原型:

- (void)addAttribute:(NSString *)name value:(id)value range:(NSRange)range;

注意,參數 value 是 id 類型的。看到這句話,你知道我想說什麼了嗎?

id 是 Objective-C 對象。而 NSInteger 是基本資料類型,不是對象。是以必須寫成 [NSNumber numberWithInteger:123] 的形式。

在設定這個值的時候,我不知道具體應該設為幾,我嘗試了好多數,但是發現竟然有的不對。後來百度了一下,才知道原來它的值有一個枚舉:

typedef NS_ENUM(NSInteger, NSUnderlineStyle) {
    NSUnderlineStyleNone                                    = 0x00,
    NSUnderlineStyleSingle                                  = 0x01,
    NSUnderlineStyleThick NS_ENUM_AVAILABLE(10_0, 7_0)      = 0x02,
    NSUnderlineStyleDouble NS_ENUM_AVAILABLE(10_0, 7_0)     = 0x09,

    NSUnderlinePatternSolid NS_ENUM_AVAILABLE(10_0, 7_0)      = 0x0000,
    NSUnderlinePatternDot NS_ENUM_AVAILABLE(10_0, 7_0)        = 0x0100,
    NSUnderlinePatternDash NS_ENUM_AVAILABLE(10_0, 7_0)       = 0x0200,
    NSUnderlinePatternDashDot NS_ENUM_AVAILABLE(10_0, 7_0)    = 0x0300,
    NSUnderlinePatternDashDotDot NS_ENUM_AVAILABLE(10_0, 7_0) = 0x0400,

    NSUnderlineByWord NS_ENUM_AVAILABLE(10_0, 7_0)            = 0x8000
} NS_ENUM_AVAILABLE(10_0, 6_0);
           

實際上,設定删除線 NSStrikethroughColorAttributeName 的時候,值也是這個枚舉。

// NSUnderlineStyleNone 不設定下劃線/删除線

// NSUnderlineStyleSingle 設定下劃線/删除線為細的單線

// NSUnderlineStyleThick 設定下劃線/删除線為粗的單線

// NSUnderlineStyleDouble 設定下劃線/删除線為細的雙線

// NSUnderlinePatternSolid 設定 下劃線/删除線樣式為連續的實線

// NSUnderlinePatternDot 設定下劃線/删除線樣式為點,也就是虛線,比如這樣:------

// NSUnderlinePatterDash 設定下劃線/删除線樣式為破折号,比如這樣:—— —— ——

// NSUnderlinePatternDashDot 設定下劃線/删除線樣式為連續的破折号和點,比如這樣:——-——-——-

// NSUnderlinePatternDashDotDot 設定下劃線/删除線樣式為連續的破折号、點、點,比如:——--——--——--

// NSUnderlineByWord 在有空格的地方不設定下劃線/删除線

我為什麼要把它們分成三段來說呢?因為它們屬于三種,設定的時候不一定隻有一種,可以同時設定其中的某兩種或三種都設定。比如這樣:

[str addAttribute:NSUnderlineStyleAttributeName value:
        [NSNumber numberWithInteger:NSUnderlineStyleDouble | NSUnderlinePatternDot] range:NSMakeRange(12, 6)];
           

這行代碼就是給 “使用者服務協定“ 加一個下劃線,但是這回的下劃線是兩行的,并且是虛線。(注意:同時滿足多項,是用 ‘|’ 運算符連接配接)

實際上下劃線的顔色也是可以設定的。如果沒有設定的話,預設和文字顔色一樣,也就是橙色。我們來嘗試把下劃線換成藍色看看:

- (void)viewDidLoad {
    [super viewDidLoad];

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, ScreenWidth, 40)];
    label.font = [UIFont systemFontOfSize:18]; // 字型大小
    label.textAlignment = NSTextAlignmentCenter; // 文字對齊方式
    
    NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:
        @"點選下一步表示您已同意《使用者服務協定》"];
    [str addAttribute:NSForegroundColorAttributeName value:
        [UIColor colorWithRed:100/255.0 green:100/255.0 blue:100/255.0 alpha:1] range:NSMakeRange(0,11)];
    [str addAttribute:NSForegroundColorAttributeName value:
        [UIColor colorWithRed:255/255.0 green:110/255.0 blue:17/255.0 alpha:1] range:NSMakeRange(11,8)];
    [str addAttribute:NSUnderlineStyleAttributeName value:
        [NSNumber numberWithInteger:NSUnderlineStyleSingle] range:NSMakeRange(12, 6)]; // 下劃線類型
    [str addAttribute:NSUnderlineColorAttributeName value:
        [UIColor blueColor] range:NSMakeRange(12, 6)]; // 下劃線顔色
    
    label.attributedText = str;
    [self.view addSubview:label];
}
           

運作一下,結果如下圖所示:

使用NSMutableAttributedString添加下劃線、删除線、陰影、填充、不同字型顔色等

我們再舉個栗子,添加一個加粗版的删除線,設定删除線的顔色為黑色(如果不設定顔色,也預設和文字顔色一樣)

- (void)viewDidLoad {
    [super viewDidLoad];

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, ScreenWidth, 40)];
    label.font = [UIFont systemFontOfSize:18]; // 字型大小
    label.textAlignment = NSTextAlignmentCenter; // 文字對齊方式
    
    NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:
        @"點選下一步表示您已同意《使用者服務協定》"];
    [str addAttribute:NSForegroundColorAttributeName value:
        [UIColor colorWithRed:100/255.0 green:100/255.0 blue:100/255.0 alpha:1] range:NSMakeRange(0,11)];
    [str addAttribute:NSForegroundColorAttributeName value:
        [UIColor colorWithRed:255/255.0 green:110/255.0 blue:17/255.0 alpha:1] range:NSMakeRange(11,8)];
    [str addAttribute:NSUnderlineStyleAttributeName value:
        [NSNumber numberWithInteger:NSUnderlineStyleSingle] range:NSMakeRange(12, 6)]; // 下劃線類型
    [str addAttribute:NSUnderlineColorAttributeName value:
        [UIColor blueColor] range:NSMakeRange(12, 6)]; // 下劃線顔色
    [str addAttribute:NSStrikethroughStyleAttributeName value:
        [NSNumber numberWithInteger:NSUnderlineStyleThick] range:NSMakeRange(12, 6)]; // 删除線類型
    [str addAttribute:NSStrikethroughColorAttributeName value:
        [UIColor blackColor] range:NSMakeRange(12, 6)]; // 删除線顔色
    
    label.attributedText = str;
    [self.view addSubview:label];
}
           

然後運作一下來看看效果:

使用NSMutableAttributedString添加下劃線、删除線、陰影、填充、不同字型顔色等

我們再舉最後一個栗子(栗子說:能不能别舉我了~),設定填充:

- (void)viewDidLoad {
    [super viewDidLoad];

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, ScreenWidth, 40)];
    label.font = [UIFont systemFontOfSize:18]; // 字型大小
    label.textAlignment = NSTextAlignmentCenter; // 文字對齊方式
    
    NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:
        @"點選下一步表示您已同意《使用者服務協定》"];
    [str addAttribute:NSForegroundColorAttributeName value:
        [UIColor colorWithRed:100/255.0 green:100/255.0 blue:100/255.0 alpha:1] range:NSMakeRange(0,11)];
    [str addAttribute:NSForegroundColorAttributeName value:
        [UIColor colorWithRed:255/255.0 green:110/255.0 blue:17/255.0 alpha:1] range:NSMakeRange(11,8)];
    [str addAttribute:NSStrokeWidthAttributeName value:
        [NSNumber numberWithFloat:3.0] range:NSMakeRange(11, 8)]; // 設定填充
    
    
    label.attributedText = str;
    [self.view addSubview:label];
}
           

然後運作一下來看看效果:

使用NSMutableAttributedString添加下劃線、删除線、陰影、填充、不同字型顔色等

同理,填充也可以設定顔色,如果不設定的話,預設和文字顔色一樣。

NSMutableAttributedString 還能設定很多其它屬性,比如段落格式、陰影等等(還有很多哦)

想要完整的學習它請參考蘋果的官方文檔:傳送門

最後想說一下它的缺點,也許有的同學已經發現了,下劃線離文字太近了!不能設定下劃線和文字的距離,這是它美中不足的地方。