【问题标题】:Highlighting search result in UITableView cell iOS Swift在 UITableView 单元格 iOS Swift 中突出显示搜索结果
【发布时间】:2016-02-06 04:33:43
【问题描述】:

我在TableView 中实现了一个搜索栏。现在我想强调结果。例如,如果我输入了两个字母,那么这两个字母应该在搜索栏下拉的结果 TableView 中突出显示。谁能帮我做到这一点?我知道我应该为此使用自定义单元格,但我无法实现它。

【问题讨论】:

  • 到目前为止你看过什么?属性字符串?显示您当前的代码
  • @Wain 不,我还没有做任何事情。但在目标 c 中看到了属性字符串的代码。不明白..你能帮我解决这个问题吗
  • @Anbu.Karthik 它没有详细的答案

标签: ios uitableview highlight searchbar


【解决方案1】:

Swift 5 版本的 Vijayvir 的回答:

let initialtext = "Hello, World!"

let attrString: NSMutableAttributedString = NSMutableAttributedString(string: initialtext)

let range = (initialtext as NSString).range(of: "World", options: .caseInsensitive)

attrString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red, range: range)

cell.textLabel?.attributedText = attrString

2020 年更新: 这是一个简单的String 扩展,您可以使用它轻松地制作属性字符串。

extension String {

    func highlightText(
        _ text: String,
        with color: UIColor,
        caseInsensitivie: Bool = false,
        font: UIFont = .preferredFont(forTextStyle: .body)) -> NSAttributedString
    {
        let attrString = NSMutableAttributedString(string: self)
        let range = (self as NSString).range(of: text, options: caseInsensitivie ? .caseInsensitive : [])
        attrString.addAttribute(
            .foregroundColor,
            value: color,
            range: range)
        attrString.addAttribute(
            .font,
            value: font,
            range: NSRange(location: 0, length: attrString.length))
        return attrString
    }

}

【讨论】:

    【解决方案2】:

    此解决方案适用于转义字符,例如 ({}[]()'") 此解决方案使用 SWIFT 5 编写。

    func generateAttributedString(with searchTerm: String, targetString: NSAttributedString) -> NSAttributedString? {
        let attributedString = NSMutableAttributedString(attributedString: targetString)
        do {
    
            let regex = try NSRegularExpression(pattern:  NSRegularExpression.escapedPattern(for: searchTerm).trimmingCharacters(in: .whitespacesAndNewlines).folding(options: .regularExpression, locale: .current), options: .caseInsensitive)
            let range = NSRange(location: 0, length: targetString.string.utf16.count)
            attributedString.addAttribute(NSAttributedString.Key.backgroundColor, value: UIColor.clear, range: range)
    
    
            for match in regex.matches(in: targetString.string.folding(options: .regularExpression, locale: .current), options: .withTransparentBounds, range: range) {
                attributedString.addAttribute(NSAttributedString.Key.backgroundColor, value: UIColor.yellow, range: match.range)
            }
            return attributedString
        } catch {
            NSLog("Error creating regular expresion: \(error)")
            return nil
        }
    }
    

    【讨论】:

      【解决方案3】:

      尽量保持苗条。 该函数返回一个属性字符串,其中出现的 searchText 以粗体显示。 斯威夫特 4.2+

        private func boldedString(with baseString: String, searchString: String, fontSize: CGFloat) -> NSAttributedString? {
          guard let regex = try? NSRegularExpression(pattern: searchString, options: .caseInsensitive) else {
              return nil
          }
      
          let attributedString = NSMutableAttributedString(string: baseString)
          let boldFont = UIFont.systemFont(ofSize: fontSize, weight: .bold)
          regex
            .matches(in: baseString, options: .withTransparentBounds,
                     range: NSRange(location: 0, length: baseString.utf16.count))
            .forEach {
              attributedString.addAttributes([.font: boldFont], range: $0.range)
          }
          return attributedString
        }
      

      在单元格中,您需要添加如下代码进行配置:

      func configure(with text: String, searchText: String?) {
        if let boldedAddress = boldedString(with: text,
                                            searchString: searchText,
                                            fontSize: titleLabel.font.pointSize) {
          titleLabel.attributedText = boldedAddress
        } else {
          titleLabel.text = locationInfo.location.address
        }
      }
      

      【讨论】:

        【解决方案4】:

        这里是tableview中属性文本的第二种方式

           let initialtext =   "Hello World"
            let attrString: NSMutableAttributedString = NSMutableAttributedString(string: initialtext)
        
        let range: NSRange = (initialtext as NSString).rangeOfString(("World" , options:NSStringCompareOptions.CaseInsensitiveSearch])
        
        
            attrString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: range)
        
        
            cell!.textLabel?.attributedText = attrString
        

        【讨论】:

          【解决方案5】:

          @Vijay 对此帖子有一个很好的正确答案。

          我通过创建一个接受searchString 和您要修改的字符串的函数来为自己的目的(在搜索结果中加粗文本)稍微修改了这个 - resultString - 并返回可应用于 UILabelattributedString

          我还检查了lowercaseString 属性,因此无论我在搜索栏中输入什么内容,我的字符串都会匹配字符而不是大小写(此要求可能会有所不同,具体取决于您的用例)。

          func boldSearchResult(searchString: String, resultString: String) -> NSMutableAttributedString {
          
              let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: resultString)
              let pattern = searchString.lowercaseString
              let range: NSRange = NSMakeRange(0, resultString.characters.count)
          
              let regex = try! NSRegularExpression(pattern: pattern, options: NSRegularExpressionOptions())
          
              regex.enumerateMatchesInString(resultString.lowercaseString, options: NSMatchingOptions(), range: range) { (textCheckingResult, matchingFlags, stop) -> Void in
                  let subRange = textCheckingResult?.range
                  attributedString.addAttribute(NSFontAttributeName, value: UIFont.customBoldedFontNameWithSize(15.0), range: subRange!)
              }
          
              return attributedString
          
          }
          

          注意:我可以使用自定义的粗体字体,但您始终可以使用 UIFont.boldSystemFontOfSize(fontSize: CGFloat) 或类似的东西来获得类似的效果。

          然后,只需执行以下操作(一些变体)将结果添加到您的标签:

          cell.myCustomLabel.attributedText = boldSearchResult(mySearchText, resultString: textForBolding)
          

          【讨论】:

          • 拯救了我的一天.. =D
          【解决方案6】:

          您可以通过从结果字符串中找到搜索词字符串范围并在该范围内添加属性字符串来实现此目的。找到下面的示例代码,

          Objective-C

          NSString *searchTerm = /* SEARCH_TERM */;
          NSString *resultText = /* YOUR_RESULT_TEXT */;
          
          NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:resultText];
          
          NSString *pattern = [NSString stringWithFormat:@"(%@)", searchTerm];
          NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:kNilOptions error:nil];
          NSRange range = NSMakeRange(0, resultText.length);
          
          [regex enumerateMatchesInString:resultText options:kNilOptions range:range usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
          
              NSRange subStringRange = [result rangeAtIndex:1];
          
              [attributedString addAttribute:NSForegroundColorAttributeName
                                       value:[UIColor redColor]
                                       range:subStringRange];
          }];
          

          斯威夫特(已测试)

          let searchTerm = "" /* SEARCH_TERM */
          let resultText = "" /* YOUR_RESULT_TEXT */
          let attributedString:NSMutableAttributedString = NSMutableAttributedString(string: resultText)
          let pattern = "(\(searchTerm))"
          let range:NSRange = NSMakeRange(0, resultText.characters.count)
          
          let regex = try! NSRegularExpression( pattern: pattern, options: NSRegularExpressionOptions())
          regex.enumerateMatchesInString(
               resultText,
               options: NSMatchingOptions(),
               range: range,
               usingBlock: {
                  (textCheckingResult, matchingFlags, stop) -> Void in
                     let subRange = textCheckingResult?.range
                      attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: subRange!)
                      }
                  )
          

          【讨论】:

          • @GaneshKumar 编辑了我的答案。
          • 我使用了谓词进行过滤。我应该在哪里使用代码..在过滤器中?还是在单元格中为RowatIndexPath?
          • @GaneshKumar 如果您使用表格视图来呈现搜索结果,那么您必须将其用作cellForRowAtIndexPath
          • @GaneshKumar 如果我的回答有用,请接受meta.stackexchange.com/questions/5234/…
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-03-17
          • 1970-01-01
          • 2014-07-25
          • 1970-01-01
          • 2014-10-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多