Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
596 views
in Technique[技术] by (71.8m points)

ios - Get currently typed word in a UITextView

I want to get the currently typed word in a UITextView. A way to get a completely typed word can be found here UITEXTVIEW: Get the recent word typed in uitextview, however, I want to get the word while it is being typed (no matter where it is typed, beginning, middle, end of UITextView).

I guess what defines a word being typed is a whitespace character followed by alphanumeric characters, or if the current location (somehow to figure out with range.location) is the beginning of the UITextView then whatever follows up should be considered as word as well. A word is finished being typed when another whitespace character follows.

I tried with:

 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text`

but I have a problem finding the correct range.

In short again: I need to find the substring in a UITextView, where substring is the currently typed word.

EDIT: Because the question came up. I'm using NSLayoutManager and bind a NSTextContainer to it, which then is passed as layoutManager to a NSTextStorage.

EDIT2: The main problem with (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text is that the range.location is not the same as the indicator is, but always 1 less. If the cursor is at position 1, after typing one letter, range.location would return 0. Any way around this? In addition the text attribute of UITextView seems to be off by 1 as well. When the text is foobar and I output the UITextView.text then I get fooba instead. Therefore range.location+1 returns the exception Range {0, 1} out of bounds; string length 0'

EDIT3: Maybe it is easier to get my wanted result with the NSTextStorage instead of UITextView?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The following is an example of a skeletal structure that uses UITextInput and UITextInputTokenizer to give the word that is being currently typed/edited.

- (void) textViewDidChange:(UITextView *)textView {

    NSRange selectedRange = textView.selectedRange;

    UITextPosition *beginning = textView.beginningOfDocument;
    UITextPosition *start = [textView positionFromPosition:beginning offset:selectedRange.location];
    UITextPosition *end = [textView positionFromPosition:start offset:selectedRange.length];

    UITextRange* textRange = [textView.tokenizer rangeEnclosingPosition:end withGranularity:UITextGranularityWord inDirection:UITextLayoutDirectionLeft];

    NSLog(@"Word that is currently being edited is : %@", [textView textInRange:textRange]);
}

This will give you the entire word that is currently being typed.

For instance if you are typing input and have typed inp it will give you inp. Further if you are in the middle of the word middle and change it to midddle, it will give you midddle. The trick here is tokenizing.

I have placed the code inside textViewDidChange: so that you get the word after it's been typed/edited. If you want it before the last character change (i.e. the word that is about to be changed), place the code in textView:shouldChangeTextInRange:replacementText:.

PS: You will have to handle edge cases like sentences and paragraphs being pasted/removed. You can modify this code to get characters/sentences/paragraphs etc, instead of just words by changing the granularity. Look into the declaration of UITextGranularity ENUM for more options:

typedef NS_ENUM(NSInteger, UITextGranularity) {
    UITextGranularityCharacter,
    UITextGranularityWord,
    UITextGranularitySentence,
    UITextGranularityParagraph,
    UITextGranularityLine,
    UITextGranularityDocument
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...