Reputation: 90
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?
Upvotes: 0
Views: 1009
Reputation: 26016
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.
Upvotes: 1