2

I have a UITextView where I would like to select a part of the text. I'm trying to use selectedTextRange, unfortunately I get this error:

Cannot convert value of type 'NSRange' (aka '_NSRange') to expected argument type 'UITextRange'

This is the code I'm trying to use:

mainTextField.becomeFirstResponder()
mainTextField.selectedTextRange = mainTextField.textInRange(matchRange) // matchRange is a NSRange

The range I'm using is coming from a Regex which I adapted from this tutorial1:

EDIT: added the first line

if let regex =  NSRegularExpression(options: searchOptions){ // refers to an installed extension convenience init
let range = NSMakeRange(0, (mainTextField.text.characters.count))
let matches = regex.matchesInString(mainTextField.text, options: [], range: range)
[...]
Cue
  • 2,952
  • 3
  • 33
  • 54

3 Answers3

4

You can add an extension on UITextView that will do the conversion.

    extension UITextView
    {
        func textRangeFromNSRange(range:NSRange) -> UITextRange?
        {
            let beginning = self.beginningOfDocument
            guard let start = self.positionFromPosition(beginning, offset: range.location), end = self.positionFromPosition(start, offset: range.length) else { return nil}

            return self.textRangeFromPosition(start, toPosition: end)
        }
    }

Use

    if let range = mainTextView.textRangeFromNSRange(range: matchRange){
        mainTextField.selectedTextRange = range
    }

Where matchRange is an NSRange and range is a UITextRange

beyowulf
  • 15,101
  • 2
  • 34
  • 40
1

Swift 4 updated version of @beyowulf's answer:

extension UITextView {

    func textRangeFromNSRange(range:NSRange) -> UITextRange? {
        let beginning = beginningOfDocument
        guard let start = position(from: beginning, offset: range.location), let end = position(from: start, offset: range.length) else { return nil }

        return textRange(from: start, to: end)
    }
}
Emma Labbé
  • 667
  • 7
  • 18
-1

Just to add a little more information, I found also an alternative way: instead of using selectedTextRange and doing the conversion, you can use selectedRange.

Note: matchRange is a NSRange

// this don't work because selectedTextRange requires an UITextRange
textField.selectedTextRange = textField.textInRange(matchRange) // don't work

// this works because selectedRange requires a NSRange
textField.selectedRange = matchRange // works
Cue
  • 2,952
  • 3
  • 33
  • 54