Detecting marked range in UI/NSTextViews at the time of shouldChangeTextIn

We have submitted a feedback for this issue: FB21230723

We're building a note-taking app for iOS and macOS that uses both UITextView and NSTextView.

When performing text input that involves a marked range (such as Japanese input) in a UITextView or NSTextView with a UITextViewDelegate or NSTextViewDelegate set, the text view's marked range (markedTextRange / markedRange()) has not yet been updated at the moment when shouldChangeTextIn is invoked.

  • UITextViewDelegate.textView(_:shouldChangeTextIn:replacementText:)
  • NSTextViewDelegate.textView(_:shouldChangeTextIn:replacementString:)

The current behavior is this when entering text in Japanese: (same for NSTextView)

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        print(textView.markedTextRange != nil)  // prints out false
        DispatchQueue.main.async {
            print(textView.markedTextRange != nil)  // prints out true
        }
}

However, we need the value of markedTextRange right away in order to determine whether to return true or false from this method.

Is there any workaround for this issue?

Detecting marked range in UI/NSTextViews at the time of shouldChangeTextIn
 
 
Q