NSRange是个使用频率比较高的对象,尤其是在设置富文本(AttributedString)的地方。自带的 rangeOfString 就可以查找某字符所在字符串中的位置。但如果要获取多次出现的位置信息就需要另辟蹊径了。如下代码实现了,获取多次出现的位置信息的方法,参考如下:
/// 获取字符出现的位置信息(支持多次位置获取)
/// - Parameter string: 原始文本
/// - Parameter inString: 需要查找的字符
private func rangeOfString(string:NSString,
andInString inString:String) -> [NSRange] {
var arrRange = [NSRange]()
var _fullText = string
var rang:NSRange = _fullText.range(of: inString)
while rang.location != NSNotFound {
var location:Int = 0
if arrRange.count > 0 {
if arrRange.last!.location + arrRange.last!.length < string.length {
location = arrRange.last!.location + arrRange.last!.length
}
}
_fullText = NSString.init(string: _fullText.substring(from: rang.location + rang.length))
if arrRange.count > 0 {
rang.location += location
}
arrRange.append(rang)
rang = _fullText.range(of: inString)
}
return arrRange
}
Swift 中本身有 Range 对象,由于对其使用方法和特性不甚了解,故使用NSRange 对象。
引申一下,批量设置AttributedString,就需要使用到如上代码,具体参考代码如下:
/// 批量设置富文本
/// - Parameter textFont: 默认文本
/// - Parameter textColor: 默认文本颜色
/// - Parameter changeTexts: 需要改变的文本
/// - Parameter changFonts: 需要改变的字体
/// - Parameter changeColors: 需要改变的颜色
/// - Parameter isLineThrough: 是否下划线
func setAttributeStringTexts(FullTextFont textFont:UIFont,
andFullTextColor textColor:UIColor,
withChangeTexts changeTexts:[String],
withChangeFonts changFonts:[UIFont],
withChangeColors changeColors:[UIColor],
isLineThrough:Bool = false) -> NSAttributedString{
let strFullText:String = self
var range:NSRange?
var dicAttr:[NSAttributedString.Key:Any]?
let attributeString = NSMutableAttributedString.init(string: strFullText)
//不需要改变的文本
range = NSString.init(string: strFullText).range(of: String.init(strFullText))
dicAttr = [
NSAttributedString.Key.font:textFont,
NSAttributedString.Key.foregroundColor:textColor,
]
attributeString.addAttributes(dicAttr!, range: range!)
//需要改变的文本
var index:Int = 0
for item in changeTexts {
//range = NSString.init(string: strFullText).range(of: item)
let ranges = self.rangeOfString(string: NSString.init(string: strFullText), andInString: item)
for range in ranges {
dicAttr = [
NSAttributedString.Key.font:changFonts.count > index ? changFonts[index] : changFonts.first as Any,
NSAttributedString.Key.foregroundColor:changeColors.count > index ? changeColors[index] : changeColors.first as Any,
]
if isLineThrough {
dicAttr?[NSAttributedString.Key.strikethroughStyle] = NSNumber.init(value: 1)
}
if range.location + range.length <= fullString.length {
attributeString.addAttributes(dicAttr!, range: range)
}
}
index += 1
}
return attributeString
}
以上代码使用效果详见如下图片:
|