当我尝试将属性添加到包含表情符号的属性字符串时,有时会破坏某些表情符号。对于常规文本工作完美。我有什么想法吗?
这是我的功能 - 它应该是粗体引号(第一个和最后一个引号之间的文字)
func boldQuotation(str: String, fontSize: CGFloat) -> NSAttributedString {
let normalAttributes = [NSFontAttributeName : UIFont.systemFontOfSize(fontSize)]
let boldAttributes = [NSFontAttributeName : UIFont.boldSystemFontOfSize(fontSize)]
let attributedStr = NSMutableAttributedString(string: str, attributes: normalAttributes)
let firstQuotationMarkRange = str.rangeOfString("\"")
let lastQuotationMarkRange = str.rangeOfString("\"", options: [.BackwardsSearch], range: nil, locale: nil)
guard let firstIndex = firstQuotationMarkRange?.startIndex, lastIndex = lastQuotationMarkRange?.endIndex else {
return attributedStr
}
attributedStr.addAttributes(boldAttributes, range: NSMakeRange(str.startIndex.distanceTo(firstIndex), firstIndex.distanceTo(lastIndex)))
return attributedStr
}
以下是无法正确归因的文字示例:
let str = "\"\""
结果如下:
我使用的是Swift 2.3,iOS 10.2.1,Xcode 8.2.1,部署目标:9.3
答案 0 :(得分:-1)
好的,经过进一步的调查(没有回答),我终于找到了那个错误的原因和解决方案。
使用NSRange
索引(从Range
获取)创建String
时出现问题。长话短说 - Swift String
范围和NSString
范围不应该用于将一个范围转换为另一个范围。至少不是这样的:
let firstQuotationMarkRange = str.rangeOfString("\"")
let lastQuotationMarkRange = str.rangeOfString("\"", options: [.BackwardsSearch], range: nil, locale: nil)
guard let firstIndex = firstQuotationMarkRange?.startIndex, lastIndex = lastQuotationMarkRange?.endIndex else {
return attributedStr
}
//THIS IS WRONG:
range = NSMakeRange(str.startIndex.distanceTo(firstIndex), firstIndex.distanceTo(lastIndex))
那么什么是正确的解决方案?首先将String转换为NSString,然后开始查找子串范围。这是固定功能:
func boldQuotation(str: String, fontSize: CGFloat) -> NSAttributedString {
let normalAttributes = [NSFontAttributeName : UIFont.systemFontOfSize(fontSize)]
let boldAttributes = [NSFontAttributeName : UIFont.boldSystemFontOfSize(fontSize)]
let attributedStr = NSMutableAttributedString(string: str, attributes: normalAttributes)
let nsStr = str as NSString
let firstQuotationMarkRange = nsStr.rangeOfString("\"")
let lastQuotationMarkRange = nsStr.rangeOfString("\"", options: [.BackwardsSearch])
guard firstQuotationMarkRange.length > 0 && lastQuotationMarkRange.length > 0 else {
return attributedStr
}
let nsrange = NSMakeRange(firstQuotationMarkRange.location, lastQuotationMarkRange.location + lastQuotationMarkRange.length - firstQuotationMarkRange.location)
attributedStr.addAttributes(boldAttributes, range: nsrange)
return attributedStr
}