首页 > 解决方案 > 如何在swift 3中搜索属性文本中的单词?

问题描述

在这里,我从一个 api 获得了属性文本,它显示在文本视图上,但后来我要求属性文本需要搜索,当搜索一个单词时,它应该在给定的 html 属性文本中显示匹配单词的突出显示颜色和为了显示属性文本,我使用了文本视图,我尝试了下面的代码,在这里我没有得到任何函数来将属性字符串传递给搜索并尝试了下面的函数,但是在文本视图中显示的 html 标签可以帮助我如何解决这个问题吗?

这是我的代码

 func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        if searchText != "" {
            let attributedString = generateAttributedString(with: searchText, targetString: (self.FAQModel?.content)!)
            self.FAQTextView.attributedText = attributedString
        }
        else {
            let attributedString = self.FAQModel?.content.htmlAttributedString(fontSize: 14.0)
            self.FAQTextView.attributedText = attributedString
        }
    }

    func generateAttributedString(with searchTerm: String, targetString: String) -> NSAttributedString? {
        let attributedString = NSMutableAttributedString(string: targetString)
        do {
            let regex = try NSRegularExpression(pattern: searchTerm, options: .caseInsensitive)
            let range = NSRange(location: 0, length: targetString.utf16.count)
            for match in regex.matches(in: targetString, options: .withTransparentBounds, range: range) {
                attributedString.addAttribute(NSAttributedStringKey.font, value: UIFont.systemFont(ofSize: 14), range: match.range)
                attributedString.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.red, range: match.range)
            }
            return attributedString
        } catch _ {
            NSLog("Error creating regular expresion")
            return nil
        }
    } 

标签: iosswift3nsattributedstring

解决方案


问题:

let attributedString = NSMutableAttributedString(string: targetString)

您正在使用您的 HTML 字符串创建一个NSAttributedString而不进行解析。所以你会看到 HTML 标签。

您已经有了自己的方法,可以将 HTML 字符串解析为NSAttributedString,使用它(请记住,我们需要一个可变的):

let attributedString = NSMutableAttributedString(attributedString: targetString.htmlAttributedString(fontSize: 14.0))

Now, the NSAttributedString conversion removed the HTML tags (and interprets them if possible, because NSAttributedString doesn't interprets ALL HTML tags, only a few ones). So the length, the ranges are all different.

So you can't do this anymore:

let range = NSRange(location: 0, length: targetString.utf16.count)

You need to update it to:

let range = NSRange(location: 0, length: attributedString.string.utf16.count)

Same here:

for match in regex.matches(in: targetString, options: .withTransparentBounds, range: range) {

To be updated to:

for match in regex.matches(in: attributedString.string, options: .withTransparentBounds, range: range) {

推荐阅读