18

I need to use NSStringFromRange but I only have a start and end UITextPositions. How do you convert UITextPosition to NSRange.

NSMutableArray * wordArray = [[NSMutableArray alloc]init];
id<UITextInputTokenizer> tokenizer = tv.tokenizer;
UITextPosition *start = tv.beginningOfDocument;
while (![start isEqual:tv.endOfDocument]) {
    UITextPosition *end = [tokenizer positionFromPosition:start toBoundary:UITextGranularityWord inDirection:UITextStorageDirectionForward];
    NSString *word = [tv textInRange:[tv textRangeFromPosition:start toPosition:end]];
    [wordArray addObject:NSStringFromRange(<#NSRange range#>)];
    start = end;
}
BDGapps
  • 3,318
  • 10
  • 56
  • 75

4 Answers4

24

Try this:

NSInteger startOffset = [tv offsetFromPosition:tv.beginningOfDocument toPosition:start];
NSInteger endOffset = [tv offsetFromPosition:tv.beginningOfDocument toPosition:end];
NSRange offsetRange = NSMakeRange(startOffset, endOffset - startOffset);
[wordArray addObject:NSStringFromRange(offsetRange)];
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITextView characterOffsetOfPosition:withinRange:]: unrecognized selector sent to instance 0x71da000' – BDGapps Jul 31 '12 at 17:56
8
- (NSRange)rangeFromTextRange:(UITextRange *)textRange inTextView:(UITextView*)textView {

    UITextPosition* beginning = textView.beginningOfDocument;
    UITextPosition* start = textRange.start;
    UITextPosition* end = textRange.end;

    const NSInteger location = [textView offsetFromPosition:beginning toPosition:start];
    const NSInteger length = [textView offsetFromPosition:start toPosition:end];

    return NSMakeRange(location, length);
}
Peter Lapisu
  • 19,915
  • 16
  • 123
  • 179
5

Swift3 version

    func angeFromTextRange(textRange:UITextRange,textView:UITextView) -> NSRange {
       let location:Int = textView.offset(from: textView.beginningOfDocument, to: textRange.start)
       let length:Int = textView.offset(from: textRange.start, to: textRange.end)
       return NSMakeRange(location, length)
}
Serge B.
  • 792
  • 10
  • 17
2

Swift 2 version for @Peter Lapisu answer

Method 1: As function

func rangeFromTextRange(textRange:UITextRange,textView:UITextView) -> NSRange {
        let location:Int = textView.offsetFromPosition(textView.beginningOfDocument, toPosition: textRange.start)
        let length:Int = textView.offsetFromPosition(textRange.start, toPosition: textRange.end)
        return NSMakeRange(location, length)
    }

Method 2: As extension

extension UITextView {
    func rangeFromTextRange(textRange:UITextRange) -> NSRange {
        let location:Int = self.offsetFromPosition(self.beginningOfDocument, toPosition: textRange.start)
        let length:Int = self.offsetFromPosition(textRange.start, toPosition: textRange.end)
        return NSMakeRange(location, length)
    }
}
Sunil Sharma
  • 2,653
  • 1
  • 25
  • 36