Search code examples
iosobjective-cnsarrayuitextview

Find text in array and return index number


I am displaying an array of strings separated by \n or linebreaks in a textview. Thanks to the \n, if there is room in the textview, each string gets its own line. However, if the width of the textview is less than the string, then the textview automatically wraps the line to the next line so that the string in effect takes two lines. Nothing wrong with this so far.

However, I want to grab the string if someone touches it. It works fine if the string fits on a line. However, if the string has been broken across two lines by textview, if the user touches the top line, I need to attach the line below to get the whole string. Or if the user touches the bottom line, I need to get and add the previous one to have a whole string.

Can anyone suggest proper way to do this?

Here is my code that grabs the line the person touches, however, it only gets the line touched and fails when it tries to calculate the index of the string in the array.

Thanks for any suggestions:

- (void) handleTap:(UITapGestureRecognizer *)recognizer{
    UITextView *textView =  (UITextView *)recognizer.view;
    CGPoint location = [recognizer locationInView:textView];
    CGPoint position = CGPointMake(location.x, location.y);
     UITextPosition *tapPosition = [textView closestPositionToPoint:position];

    UITextRange *textRange = [textView.tokenizer rangeEnclosingPosition:tapPosition withGranularity:UITextGranularityLine inDirection:UITextLayoutDirectionRight];
//In following line, I am not getting the full text in the string, only the text of that line.  I need to get the whole string.
    NSString *tappedLine = [textView textInRange:textRange];
    NSArray* myArray  = [self.listSub.text componentsSeparatedByString:@"\n"];     
      NSInteger indexOfTheObject = [myArray indexOfObject: tappedLine];
//If the tapped line is not the same thing as the string, the above index becomes huge number like 94959494994949494 ie an error, not the index I want.
    }

Solution

  • This is indeed possible.

    First, you need to change the granularity to UITextGranularityParagraph:

    UITextRange *textRange = [textView.tokenizer rangeEnclosingPosition:tapPosition withGranularity:UITextGranularityParagraph inDirection:UITextLayoutDirectionRight];
    

    This will return you the entire wrapped line of text that the user tapped, no matter where they tapped it.

    However, this text will include the trailing \n character that marks the end of the paragraph. You need to remove this before comparing the text to your array. Replace the last line of your code above with these two lines:

    NSString *trimmedLine = [tappedLine stringByTrimmingCharactersInSet:
                                  [NSCharacterSet newlineCharacterSet]];
    NSInteger indexOfTheObject = [myArray indexOfObject: trimmedLine];