字符串内带下划线的搜索文本 Swift
Underlined Search Text Inside String Swift
我正在尝试在字符串中添加粗体和带下划线的搜索文本。我已经尝试过这个解决方案,但它只是给了我一个错误。
这是我的配置
func configure(model: SmartSearchGroupViewModel, searchedKey: String) {
let boldUnderlined = NSAttributedString(string: searchedKey, attributes: [.font: UIFont.sfProTextBold(size: 15), .underlineStyle: NSUnderlineStyle.single.rawValue])
let content = NSMutableAttributedString.init(string: model.name)
content.addAttribute(NSAttributedString.Key.font, value: UIFont.sfProTextRegular(size: 15), range: NSRange.init(location: 0, length: content.length))
if model.name.substring(from: 0) == searchedKey.substring(from: 0) {
content.addAttribute(NSAttributedString.Key.underlineStyle, value: 1, range: NSRange.init(location: 0, length: boldUnderlined.string.count))
}
groupNameLabel.attributedText = content
}
但是我得到一个错误
Cannot convert value of type 'Int' to expected argument type 'String.Index'
可以这样做:
首先用默认属性初始化属性字符串:
let content = NSMutableAttributedString.init(string: model.name)
content.addAttribute(NSAttributedString.Key.font, value: UIFont.sfProTextRegular(size: 15), range: NSRange.init(location: 0, length: content.length))
//Here, if you don't want to use the `NSRange`, you can use instead:
let content = NSMutableAttributedString(string: model.name, attributes: [NSAttributedString.Key.font: UIFont.sfProTextRegular(size: 15)])
然后,要添加搜索特效,可以使用:
解决方案 1:
let searchRange = (content.string as NSString).range(of: searchedKey)
if searchRange.location != NSNotFound {
content.addAttribute(NSAttributedString.Key.underlineStyle, value: 1, range: searchRange)
}
解决方案2:
if let search = content.string.range(of: searchedKey) {
let searchNSRange = NSRange(search, in: content.string)
content.addAttribute(NSAttributedString.Key.underlineStyle, value: 1, range: searchNSRange)
}
Solution1 和 Solution2 之间的区别,是使用 range(of:)
应用于 NSString
或 String
,它将输出 NSRange
或 Range
。由于 NSAttributedString
使用 NSRange
,解决方案一可能写起来“更快”。
旁注,如果您还想搜索 non-case 敏感信息,可以使用 .range(of: searchedKey, options: .caseInsensitive) (and even put the local parameter:
.range(of: searchedKey, options: .caseInsensitive, locale: .current)`.
我注意到你的代码 NSRange.init(location: 0, length: boldUnderlined.string.count)
,请注意 Swift 上的计数可能与 NSFoundation 中的 length
不同。即 UTF8 与 UTF16 计数。因此,请改用 string.utf16.count
,或直接使用 length
。
我正在尝试在字符串中添加粗体和带下划线的搜索文本。我已经尝试过这个解决方案,但它只是给了我一个错误。
这是我的配置
func configure(model: SmartSearchGroupViewModel, searchedKey: String) {
let boldUnderlined = NSAttributedString(string: searchedKey, attributes: [.font: UIFont.sfProTextBold(size: 15), .underlineStyle: NSUnderlineStyle.single.rawValue])
let content = NSMutableAttributedString.init(string: model.name)
content.addAttribute(NSAttributedString.Key.font, value: UIFont.sfProTextRegular(size: 15), range: NSRange.init(location: 0, length: content.length))
if model.name.substring(from: 0) == searchedKey.substring(from: 0) {
content.addAttribute(NSAttributedString.Key.underlineStyle, value: 1, range: NSRange.init(location: 0, length: boldUnderlined.string.count))
}
groupNameLabel.attributedText = content
}
但是我得到一个错误
Cannot convert value of type 'Int' to expected argument type 'String.Index'
可以这样做:
首先用默认属性初始化属性字符串:
let content = NSMutableAttributedString.init(string: model.name)
content.addAttribute(NSAttributedString.Key.font, value: UIFont.sfProTextRegular(size: 15), range: NSRange.init(location: 0, length: content.length))
//Here, if you don't want to use the `NSRange`, you can use instead:
let content = NSMutableAttributedString(string: model.name, attributes: [NSAttributedString.Key.font: UIFont.sfProTextRegular(size: 15)])
然后,要添加搜索特效,可以使用:
解决方案 1:
let searchRange = (content.string as NSString).range(of: searchedKey)
if searchRange.location != NSNotFound {
content.addAttribute(NSAttributedString.Key.underlineStyle, value: 1, range: searchRange)
}
解决方案2:
if let search = content.string.range(of: searchedKey) {
let searchNSRange = NSRange(search, in: content.string)
content.addAttribute(NSAttributedString.Key.underlineStyle, value: 1, range: searchNSRange)
}
Solution1 和 Solution2 之间的区别,是使用 range(of:)
应用于 NSString
或 String
,它将输出 NSRange
或 Range
。由于 NSAttributedString
使用 NSRange
,解决方案一可能写起来“更快”。
旁注,如果您还想搜索 non-case 敏感信息,可以使用 .range(of: searchedKey, options: .caseInsensitive) (and even put the local parameter:
.range(of: searchedKey, options: .caseInsensitive, locale: .current)`.
我注意到你的代码 NSRange.init(location: 0, length: boldUnderlined.string.count)
,请注意 Swift 上的计数可能与 NSFoundation 中的 length
不同。即 UTF8 与 UTF16 计数。因此,请改用 string.utf16.count
,或直接使用 length
。