在我們日常開發中經常會用到屬性字,比如這樣一個很普通的需求。
先不要管為啥前面有了人民幣符號後面還要加個”元” ,純粹為了屬性字多點。 這一小段文字 有四種顏色和字型。錢和地址是從介面抓的,其他是我們前端寫的,一般情況應該怎麼寫呢 ?
普通玩兒法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
private func normalAttr(money:String,addr:String)->NSMutableAttributedString{ let starAttr = NSMutableAttributedString(string:"¥ ") starAttr.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: NSMakeRange(0,starAttr.length)) starAttr.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(18), range: NSMakeRange(0,starAttr.length)) let moneyAttr = NSMutableAttributedString(string:money) moneyAttr.addAttribute(NSForegroundColorAttributeName, value: UIColor.blackColor(), range: NSMakeRange(0,moneyAttr.length)) moneyAttr.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(14), range: NSMakeRange(0,moneyAttr.length)) let yAttr = NSMutableAttributedString(string:" 元") yAttr.addAttribute(NSForegroundColorAttributeName, value: UIColor.lightGrayColor(), range: NSMakeRange(0,yAttr.length)) yAttr.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(10), range: NSMakeRange(0,yAttr.length)) let addrAttr = NSMutableAttributedString(string:" \(addr)") addrAttr.addAttribute(NSForegroundColorAttributeName, value: UIColor.blueColor(), range: NSMakeRange(0,addrAttr.length)) addrAttr.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(14), range: NSMakeRange(0,addrAttr.length)) starAttr.appendAttributedString(moneyAttr) starAttr.appendAttributedString(yAttr) starAttr.appendAttributedString(addrAttr) return starAttr } |
寫一個方法 傳入一個money,addr 。然後進行組裝。程式碼有點長,但也算實現了需求。
但如果專案中有很多這種類似的屬性字 ,每次都要寫這麼多程式碼,著實有點痛,有沒有高階點的玩兒法呢?
鏈式玩兒法
首先對一些基礎的操作稍作封裝
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
extension NSMutableAttributedString{ func foreColor(color:UIColor)->NSMutableAttributedString{ self.addAttributes([NSForegroundColorAttributeName:color], range: self.allRange()) return self } func font(font:UIFont)->NSMutableAttributedString{ self.addAttributes([NSFontAttributeName:font], range: self.allRange()) return self } func allRange()->NSRange{ return NSMakeRange(0,self.length) } } extension String{ func toAttr()->NSMutableAttributedString{ return NSMutableAttributedString(string: self) } } |
注意 我在設定顏色和字型的時候都返回了self,以便鏈式呼叫
1 2 3 4 5 6 7 8 |
infix operator >>> { associativity left } func >>> (attr1 : NSMutableAttributedString ,attr2 : NSMutableAttributedString ) -> NSMutableAttributedString{ attr1.appendAttributedString(attr2) return attr1 } |
然後再自定義一個操作符
那麼現在怎麼玩兒呢?
1 2 3 4 5 6 7 8 9 |
func linkedAttr(money:String,addr:String) -> NSMutableAttributedString { return "¥ ".toAttr().foreColor(UIColor.redColor()).font(UIFont.systemFontOfSize(18)) >>> money.toAttr().foreColor(UIColor.blackColor()).font(UIFont.systemFontOfSize(14)) >>> " 元".toAttr().foreColor(UIColor.lightGrayColor()).font(UIFont.systemFontOfSize(10)) >>> " \(addr)".toAttr().foreColor(UIColor.blueColor()).font(UIFont.systemFontOfSize(14)) } |
以後所有這種類似的屬性字也都這麼鏈式呼叫了 ,程式碼量減少了好多 。
1 2 |
demoLabel.attributedText = self.normalAttr("1500", addr: "南京東路步行街") linkLabel.attributedText = self.linkedAttr("190000", addr: "人民廣場地下車庫") |
呼叫的程式碼,效果一樣一樣的
函式式的玩兒法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
typealias Attribute = NSMutableAttributedString -> NSMutableAttributedString func >>> (attr1:Attribute , attr2 : Attribute) -> Attribute{ return { attr in return attr1(attr2(attr)) } } func zz_foreColor(color:UIColor)->Attribute{ return { attr in attr.addAttributes([NSForegroundColorAttributeName:color], range: attr.allRange()) return attr } } func zz_font(font:UIFont)->Attribute{ return { attr in attr.addAttributes([NSFontAttributeName:font], range: attr.allRange()) return attr } } |
先宣告一個函式的型別,過載下運算子。
這種是先把所有屬性裝配好再傳入attr
1 2 3 4 5 6 7 8 9 10 11 |
func functionalAttr(money:String,addr:String)->NSMutableAttributedString{ return (zz_foreColor(UIColor.redColor()) >>> zz_font(UIFont.boldSystemFontOfSize(18)))("¥ ".toAttr()) >>> (zz_foreColor(UIColor.blackColor()) >>> zz_font(UIFont.boldSystemFontOfSize(14)))(money.toAttr()) >>> (zz_foreColor(UIColor.lightGrayColor()) >>> zz_font(UIFont.boldSystemFontOfSize(10)))(" 元".toAttr()) >>> (zz_foreColor(UIColor.blueColor()) >>> zz_font(UIFont.boldSystemFontOfSize(14)))(" \(addr)".toAttr()) } |
呼叫的地方
1 2 3 |
demoLabel.attributedText = self.normalAttr("1500", addr: "南京東路步行街") linkLabel.attributedText = self.linkedAttr("190000", addr: "人民廣場地下車庫") functionalLabel.attributedText = self.linkedAttr("9930000", addr: "函式式的測試地址") |
三種玩兒 喜歡哪個用哪個。程式碼順便上傳github,供大家參考