簡體   English   中英

突出顯示 UITableView 單元格 iOS Swift 中的搜索結果

[英]Highlighting search result in UITableView cell iOS Swift

我在TableView實現了一個搜索欄。 現在我想突出顯示結果。 例如,如果我輸入了兩個字母,那么這兩個字母應該在從搜索欄下拉的結果TableView中突出顯示。 誰能幫我做到這一點? 我知道我應該為此使用自定義單元格,但我無法實現它。

這是在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

@Vijay 對這篇文章有一個很好的、正確的答案。

為了我自己的目的(在我的搜索結果中加粗文本),我通過創建一個接受searchString和您要修改的字符串( resultString )並返回一個可以應用於UILabelattributedString字符串的函數, searchString修改了resultString

我還檢查了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)

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
    }

}

您可以通過從結果字符串中查找搜索詞字符串范圍並在該范圍內添加屬性字符串來實現這一點。 找到下面的示例代碼,

目標-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!)
            }
        )

盡量讓它保持苗條。 該函數返回一個帶有粗體的 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
  }
}

此解決方案適用於轉義字符,例如 ( {}[]()'" ) 此解決方案以 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
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM