设置前景色只对 NSAttributedString 起作用一次 [英] Setting foreground color works only once for NSAttributedString

查看:37
本文介绍了设置前景色只对 NSAttributedString 起作用一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

字符串的phone部分获得了下划线属性,但颜色保持红色.我已经将颜色和下划线分开了 setAttributes() 调用,为了清楚起见,在一次调用时也会发生同样的情况.

The phone part of the string gets the underline attribute, but the color remains red. I've separated the color and underline setAttributes() calls, to make things clear, the same happens when it's one call.

    let text = "call "
    let phone = "1800-800-900"

    let attrString = NSMutableAttributedString(string: text + phone, attributes: nil)
    let rangeText = (attrString.string as NSString).range(of: text)
    let rangePhone = (attrString.string as NSString).range(of: phone)

    attrString.setAttributes([NSAttributedStringKey.foregroundColor: UIColor.red],
                             range: rangeText)

    attrString.setAttributes([NSAttributedStringKey.foregroundColor: UIColor.blue],
                             range: rangePhone)

    attrString.setAttributes([NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue],
                             range: rangePhone)

推荐答案

来自 setAttributes():

这些新属性替换了以前与aRange 中的字符.

These new attributes replace any attributes previously associated with the characters in aRange.

换句话说,它会替换它们,擦除之前设置的所有内容,因此当您添加下划线时,它会删除该范围内的颜色.

So in other words, it replace them, erasing all previously set, so when you add the underline, it removes the color at that range.

解决办法,使用addAttributes()代替setAttributes():

let text = "call "
let phone = "1800-800-900"

let attrString = NSMutableAttributedString(string: text + phone, attributes: nil)
let rangeText = (attrString.string as NSString).range(of: text)
let rangePhone = (attrString.string as NSString).range(of: phone)

attrString.addAttributes([NSAttributedStringKey.foregroundColor: UIColor.red],
                         range: rangeText)

attrString.addAttributes([NSAttributedStringKey.foregroundColor: UIColor.blue],
                         range: rangePhone)

attrString.addAttributes([NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue],
                         range: rangePhone)

其他解决方案,使用两个NSAttributedString(我也去掉了枚举中的NSAttributedStringKey)

Other solution, use two NSAttributedString (I also remove the NSAttributedStringKey in the enum)

let textAttrStr = NSAttributedString(string:text, attributes:[.foregroundColor: UIColor.red])
let phoneAttrStr = NSAttributedString(string:phone, attributes:[.foregroundColor: UIColor.blue,
                                                               .underlineStyle: NSUnderlineStyle.styleSingle.rawValue])

let finalAttrStr = NSMutableAttributedString.init(attributedString: textAttrStr)
finalAttrStr.append(phoneAttrStr)

第一个解决方案可能存在的问题:
range(of:) 仅返回第一次出现的范围.换句话说,如果 text = "1800 " 和 phone = "18",你会得到不需要的结果.因为 rangePhone 将从索引 0 到 1,而不是 1800 18 中的 7 到 8.第二个不会出现这个问题.

Possible issue with the first solution:
range(of:) returns the range of the first occurence only. In other words, if text = "1800 " and phone = "18", you'll get unwanted results. because rangePhone would be from index 0 to 1, and not 7 to 8 in 1800 18. This issue won't happen in the second one.

这篇关于设置前景色只对 NSAttributedString 起作用一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆