I have a UITextView in which I would like to add a background to the text (hightlight it). I want everything but new lines to be highlighted. How can I achieve this?
1 Answer
You can enumerate (enumerate(_:in:option:)) on the NSAttributedString.Key.backgroundColor to find change only when it has a background. Then, you can use a regex, or a while loop with range(of:) to find where they are, and remove the .backgroundColor on them:
With sample code on Playgrounds:
func highlights() -> UITextView { let tv = UITextView(frame: CGRect(x: 0, y: 0, width: 300, height: 200)) tv.backgroundColor = .orange let text = "Hello world! How are you today?\nLet's start do some testing.\nAnd this is a long paragraph just to see it to the end of the line." let attributes: [NSAttributedString.Key: Any] = [.font: UIFont.boldSystemFont(ofSize: 15.0), .backgroundColor: UIColor.systemPink] let first = NSAttributedString(string: text, attributes: attributes) let second = NSMutableAttributedString(string: text, attributes: attributes) guard let regex = try? NSRegularExpression(pattern: "\n", options: []) else { return tv } second.enumerateAttribute(.backgroundColor, in: NSRange(location: 0, length: second.length), options: []) { attribute, range, stop in guard attribute as? UIColor != nil else { return } guard let subrange = Range(range, in: second.string) else { return } let substring = String(second.string[subrange]) let ranges = regex.matches(in: substring, options: [], range: NSRange(location: 0, length: substring.utf16.count)) ranges.forEach { second.removeAttribute(.backgroundColor, range: $0.range) } } let total = NSMutableAttributedString() total.append(first) total.append(NSAttributedString(string: "\nNormal Text, nothing to see here\n")) total.append(second) total.append(NSAttributedString(string: "\nNormal Text, nothing to see here\n")) tv.attributedText = total return tv } let tv = highlights() Side note: I didn't handle the case if you have in the string "\n \n", that might need some changes in the regex pattern. After a quick test, then NSRegularExpression(pattern: "\n(\\s+\n)*", options: []) might do the trick.
1 Comment
Lobont Andrei
Works like a charm, thanks! :)

NSAttributedStringorUITextViewselectedRange, depending on what you really want?NSAttributedString, I'm not sure if empty lines would have the background. Did you checked beforehand?