设置前景色仅对 NSAttributedString 有效一次
Setting foreground color works only once for NSAttributedString
字符串的phone部分得到下划线属性,但颜色保持红色。我已经将颜色和下划线分开 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.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
的第二次和第三次调用,因为后者会覆盖前面的。将样式组合在一个数组中:
attrString.setAttributes([.foregroundColor: UIColor.blue,
.underlineStyle: NSUnderlineStyle.styleSingle.rawValue],
range: rangePhone)
结果:
来自 setAttributes()
的文档:
These new attributes replace any attributes previously associated with
the characters in aRange.
所以换句话说,它会替换它们,擦除之前设置的所有内容,因此当您添加下划线时,它会删除该范围内的颜色。
解决方法,用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
)
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:)
returns 仅限第一次出现的范围。
换句话说,如果 text = "1800 " 和 phone = "18",您将得到不需要的结果。因为 rangePhone
将从索引 0 到 1,而不是 1800 18
中的 7 到 8。第二个不会出现这个问题
字符串的phone部分得到下划线属性,但颜色保持红色。我已经将颜色和下划线分开 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.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
的第二次和第三次调用,因为后者会覆盖前面的。将样式组合在一个数组中:
attrString.setAttributes([.foregroundColor: UIColor.blue,
.underlineStyle: NSUnderlineStyle.styleSingle.rawValue],
range: rangePhone)
结果:
来自 setAttributes()
的文档:
These new attributes replace any attributes previously associated with the characters in aRange.
所以换句话说,它会替换它们,擦除之前设置的所有内容,因此当您添加下划线时,它会删除该范围内的颜色。
解决方法,用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
)
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:)
returns 仅限第一次出现的范围。
换句话说,如果 text = "1800 " 和 phone = "18",您将得到不需要的结果。因为 rangePhone
将从索引 0 到 1,而不是 1800 18
中的 7 到 8。第二个不会出现这个问题