背景:做app經(jīng)常遇到一段話水援,不同的內(nèi)容需要不一樣的字體或顏色來顯示。這種情況用NSMutableAttributedString,需要的代碼量有點(diǎn)多。需求往往是一個部分一個屬性际乘,所以用多個部分拼湊來構(gòu)成NSAttributedString 這樣更符合業(yè)務(wù)邏輯坡倔。(靈感來自flutter)
包括兩種樣式:1.aaBB 的分塊樣式漂佩,2.aaBBaa 的插入式的樣式
(情況一: aaBB樣式有明確的分塊)
1.代碼
extension NSMutableAttributedString {
? ? convenienceinit?(elements: [(str :String, attr : [NSAttributedString.Key:Any])]) {
? ? ? ? guardelements.count>0else{
? ? ? ? ? ? returnnil
? ? ? ? }
? ? ? ? letallString:String= elements.reduce("") { (res, ele) ->Stringin
? ? ? ? ? returnres+ele.str
? ? ? ? }
? ? ? ? self.init(string: allString)
? ? ? ? foreleinelements {
? ? ? ? ? ? leteleStr = ele.str
? ? ? ? ? ? letrange:Range= allString.range(of: eleStr)!
? ? ? ? ? ? letnsRange:NSRange=NSRange(range, in: allString)
? ? ? ? ? ? self.addAttributes(ele.attr, range: nsRange)
? ? ? ? }
? ? }
}
2.使用
let lab = UILabel(frame: CGRect(x: 100, y: 200, width: 300, height: 100))
? ? ? ? view.addSubview(lab)
? ? ? ? let headStr = "head"
? ? ? ? let centerStr = "center"
? ? ? ? let backStr = "back"
? ? ? ? let attrStr = NSMutableAttributedString(elements: [
? ? ? ? ? ? (str: headStr, attr: [NSAttributedString.Key.foregroundColor : UIColor.black, NSAttributedString.Key.font
? ? ? ? ? ? ? ? : UIFont.systemFont(ofSize: 14)]),
? ? ? ? ? ? (str: centerStr, attr: [NSAttributedString.Key.foregroundColor : UIColor.yellow, NSAttributedString.Key.font
? ? ? ? ? ? ? ? : UIFont.systemFont(ofSize: 30)]),
? ? ? ? ? ? (str: backStr, attr: [NSAttributedString.Key.foregroundColor : UIColor.green, NSAttributedString.Key.font
? ? ? ? ? ? ? ? : UIFont.systemFont(ofSize: 50)])
? ? ? ? ])
? ? ? ? lab.attributedText = attrStr
3.效果圖
(情況二: aaBBaa 中間插入的樣式),Global.SMEmptyIndicator = "--",?Global.SMReplaceIndicator = "****"
Extension String {
/// replace ****?use case:?報名10天結(jié)束
?/// - Parameter newStr: newStr
?func replaceXXXX(newStr: String?) -> String {
?guard newStr != nil else {
? ? ? ? ? ? ? ? ? ? ?return self.replacingOccurrences(of: Global.SMReplaceIndicator, with: Global.SMEmptyIndicator)
? ? ? ? ? ?}
? ? ? ? return self.replacingOccurrences(of: Global.SMReplaceIndicator, with: newStr!)
? ? ? ?}
}
extension?UILabel {
?/// set UILabel attributes
?/// -?Parameters:
?///?- str: text
?///?- color: textColor
?///?- fontSize: font.size
?func?setOriginalAttr(str: String, color: UIColor, fontSize: CGFloat) {
?setOriginalAttr(str: str, color: color, font: UIFont.systemFont(ofSize: fontSize))
?}
?func?setOriginalAttr(str: String, color: UIColor, font: UIFont) {
?self.text = str
?self.textColor = color
?self.font = font
?}
?/// set one part replace?"***" of UILabel's text. You must transfer this func after you transferred setOriginalAttr
?/// -?Parameters:
?///?- partStr: this part's text
?///?- partColor:?this part's text color
?///?- partFontSize:?this part's font.size
?func?setPartAttr(partStr: String?, partColor: UIColor, partFontSize: CGFloat) {
?setPartAttr(partStr: partStr, partColor: partColor, partFont: UIFont.systemFont(ofSize: partFontSize))
?}
?func?setPartAttr(partStr: String?, partColor: UIColor, partFont: UIFont) {
?guard?self.text !=?nil?&&?self.text!.notEmpty?else?{
?return
?}
?var?rightPartStr: String = partStr ?? Global.SMEmptyIndicator
?if?partStr ==?nil?|| partStr!.isEmpty {
?rightPartStr = Global.SMEmptyIndicator
?}
?let?tempStr =?self.text!.replaceXXXX(newStr: rightPartStr)
?let?attrS = NSMutableAttributedString(string: tempStr)
?guard?let?tempRange = tempStr.range(of: rightPartStr)?else?{
?return
?}
?attrS.addAttributes([NSAttributedString.Key.foregroundColor :?self.textColor ?? UIColor.black, NSAttributedString.Key.font :?self.font ?? UIFont.systemFont(ofSize: 16)], range: NSRange(location: 0, length: tempStr.count))
?attrS.addAttributes([NSAttributedString.Key.foregroundColor : partColor, NSAttributedString.Key.font : partFont], range: tempStr.nsRange(from: tempRange))
?self.attributedText = attrS
?}
}