What I'm trying to do:
There is an attributed text in UITextView
, when user tap somewhere on text (not selecting text, just placing blinking cursor somewhere else) the whole sentence around cursor changes color.
How I tried to do this:
private func setFocus(boundarySymbols: CharacterSet) {
let mutableString = NSMutableAttributedString(attributedString: noteTextView.attributedText)
mutableString.beginEditing()
unfocusWholeText(mutableString: mutableString)
let selectedRange = noteTextView.selectedRange
guard let caretPosition = findCaretPosition() else { return }
guard let focusRange = findRangeToFocus(in: noteTextView.text, around: caretPosition, of: boundarySymbols) else { return }
text.addAttribute(NSForegroundColorAttributeName, value: ThemeManager.theme.note.text, range: focusRange)
mutableString.endEditing()
noteTextView.attributedText = mutableString
noteTextView.selectedRange = selectedRange
}
Works great when I'm calling this function in shouldChangeTextIn
method of UITextViewDelegate
, but it works only when user is typing, I would like to call this also when user only changes selection so textViewDidChangeSelection
seems to fit perfectly.
But there is a problem:
When I assign modified attributedString to UITextView
it moves cursor to the end of text (fixed it with saving cursor position and setting it again after all changes). But the problem is that both of these things are moving cursor and that invokes textViewDidChangeSelection
again so infinite loop happens (textViewDidChangeSelection
is calling my setFocus
which is modifing cursor position so is calling textViewDidChangeSelection
again).
So the question is:
Can I change attributes (basically just color) of attributedString without creating NSMutableAttributedString and reassigning it to UITextView.attributedText again to omit moving cursor to end of the text and back?
Or maybe there is a way to somehow turn off moving that cursor around when it shouldn't or make it not calling delegate for a while?