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.
Asked
Active
Viewed 2.0k times
32

Peter Lapisu
- 19,915
- 16
- 123
- 179

Milo
- 5,041
- 7
- 33
- 59
4 Answers
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);
}

Vitaly S.
- 2,389
- 26
- 40
24
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)
}
}

Laszlo
- 2,803
- 2
- 28
- 33

Daniel Wood
- 4,487
- 3
- 38
- 36
7
UITextView
has a property
@property(nonatomic) NSRange selectedRange;

yasirmturk
- 1,924
- 2
- 22
- 32
-
8This doesn't answer the OP's question. There are valid reasons why you need to convert from `UITextRange` to `NSRange`. – Stunner Mar 01 '15 at 04:01
-
Also, it doesn't exist in swift – Daniel Feb 09 '16 at 13:35
-
Also, UITextField only has `selectedTextRange`, so you need convert to a simple `NSRange` – Leslie Godwin Aug 24 '20 at 06:44
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
}
}
}

Leslie Godwin
- 2,601
- 26
- 18
-
Your code will be cleaner if you begin with `guard let.. else { return nil }` instead of the way you've written it. – kwiknik Mar 10 '23 at 16:58