35

How can I convert a UITextRange object to an NSRange? I've seen plenty of SO posts about going the other direction but that's the opposite of what I need. I'm using the UITextRange selectedTextRange which is a property of a UITextView. It returns a UITextRange but I need a range.

4 Answers 4

58

You need something like this:

- (NSRange) selectedRangeInTextView:(UITextView*)textView { UITextPosition* beginning = textView.beginningOfDocument; UITextRange* selectedRange = textView.selectedTextRange; UITextPosition* selectionStart = selectedRange.start; UITextPosition* selectionEnd = selectedRange.end; const NSInteger location = [textView offsetFromPosition:beginning toPosition:selectionStart]; const NSInteger length = [textView offsetFromPosition:selectionStart toPosition:selectionEnd]; return NSMakeRange(location, length); } 
Sign up to request clarification or add additional context in comments.

Comments

25

Here's a Swift extension based on the answer by Vitaly S.

extension UITextInput { var selectedRange: NSRange? { guard let range = self.selectedTextRange else { return nil } let location = offsetFromPosition(beginningOfDocument, toPosition: range.start) let length = offsetFromPosition(range.start, toPosition: range.end) return NSRange(location: location, length: length) } } 

Swift 4

extension UITextInput { var selectedRange: NSRange? { guard let range = selectedTextRange else { return nil } let location = offset(from: beginningOfDocument, to: range.start) let length = offset(from: range.start, to: range.end) return NSRange(location: location, length: length) } } 

Comments

8

UITextView has a property

@property(nonatomic) NSRange selectedRange; 

3 Comments

This doesn't answer the OP's question. There are valid reasons why you need to convert from UITextRange to NSRange.
Also, it doesn't exist in swift
Also, UITextField only has selectedTextRange, so you need convert to a simple NSRange
0

Swift 5

extension UITextInput { var selectedRange: NSRange? { if let selectedRange = self.selectedTextRange { return NSMakeRange(self.offset(from: self.beginningOfDocument, to: selectedRange.start), self.offset(from: selectedRange.start, to: selectedRange.end)) } else { return nil } } } 

1 Comment

Your code will be cleaner if you begin with guard let.. else { return nil } instead of the way you've written it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.