简体   繁体   中英

NSAttributedString not working for UILabel

I looked around SO and couldn't find this exact problem, despite there being a few questions with similar titles.

All I want to do is have some matching text on UILabel be drawn in BOLD. I'm using it when I'm searching for objects, it should 'bolden' the search term. To this aim, I wrote the following code:

extension String {

  func boldenOccurrences(of searchTerm: String?, baseFont: UIFont, textColor: UIColor) -> NSAttributedString {

    let defaultAttributes: [String : Any] = [NSForegroundColorAttributeName : textColor,
                                             NSFontAttributeName: baseFont]

    let result = NSMutableAttributedString(string: self, attributes: defaultAttributes)

    guard let searchTerm = searchTerm else {
        return result
    }

    guard searchTerm.characters.count > 0 else {
        return result
    }

    // Ranges.  Crash course:
    //let testString = "Holy Smokes!"
    //let range = testString.startIndex ..< testString.endIndex
    //let substring = testString.substring(with: range)  // is the same as testString

    var searchRange = self.startIndex ..< self.endIndex  //whole string
    var foundRange: Range<String.Index>!

    let boldFont = UIFont(descriptor: baseFont.fontDescriptor.withSymbolicTraits(.traitBold)!, size: baseFont.pointSize)

    repeat {

        foundRange = self.range(of: searchTerm, options: .caseInsensitive , range: searchRange)

        if let found = foundRange {

            // now we have to do some stupid stuff to make Range compatible with NSRange
            let rangeStartIndex = found.lowerBound
            let rangeEndIndex = found.upperBound

            let start = self.distance(from: self.startIndex, to: rangeStartIndex)
            let length = self.distance(from: rangeStartIndex, to: rangeEndIndex)

            log.info("Bolden Text: \(searchTerm) in \(self), range: \(start), \(length)")
            let nsRange = NSMakeRange(start, length)

            result.setAttributes([NSForegroundColorAttributeName : textColor,
                                  NSFontAttributeName: boldFont], range: nsRange)


            searchRange = found.upperBound ..< self.endIndex

        }

    } while foundRange != nil

    return result

  }
}

Everything "looks" fine. The log statement spits out what I expect and it's all good. However, when drawn on the UILabel, sometimes an entire string is set to bold, and I don't understand how that could be happening. Nothing in the code suggests this should be happening.

I set the result of this above method in a typical UITableCell configuration method (ie tableView(cellForRowAt indexPath:.... ) )

cell.titleLabel.attributedText = artist.displayName.emptyIfNil.boldenOccurrences(of: source.currentSearchTerm, baseFont: cell.titleLabel.font, textColor: cell.titleLabel.textColor)

Your primary issue is the cell reuse, maybe when a cell is reused keep your font bold as font, and that is why you have this issue, you can solve this in your cell prepareForReuse() method you can add

override func prepareForReuse() {
        super.prepareForReuse()
        //to fix ipad Error
        self.titleLabel.font = UIFont(name: "YourBaseFont", size: yourFontSize) 
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM