在iOS開發中,有時會遇到需要添加下劃線,或者設置字符串中某幾個字的顏色的情況,最常見的栗子就是注冊頁面,如圖所示:
幾乎所有注冊頁面中都會出現這麼一句話 “點擊下一步表示您已同意《用戶服務協議》”,而且可以看到,“《用戶服務協議》”幾個字是橙色的,並且它們下面還有下劃線。這是怎麼實現的呢?
有的同學可能會說:“不同顏色就設置兩個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]; }
然後我們又給這個字符串添加了一個屬性,這個屬性還是 NSForegroundColorAttributedName,但是顏色是橙色,並且范圍是從第11(別忘了編號從0開始)個字開始,一共8個字。這個范圍其實就是 “《用戶服務協議》“(書名號也算)
現在我們運行程序來看看效果:
文字顏色已經搞定了,接下來我們來加下劃線。我們在原來代碼的基礎上再加一句話:
- (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]; }
運行一下,結果如下圖所示:
我們再舉個栗子,添加一個加粗版的刪除線,設置刪除線的顏色為黑色(如果不設置顏色,也默認和文字顏色一樣)
- (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]; }
我們再舉最後一個栗子(栗子說:能不能別舉我了~),設置填充:
- (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 還能設置很多其它屬性,比如段落格式、陰影等等(還有很多哦)
想要完整的學習它請參考蘋果的官方文檔:傳送門
最後想說一下它的缺點,也許有的同學已經發現了,下劃線離文字太近了!不能設置下劃線和文字的距離,這是它美中不足的地方。