如何将NSRange转换为Range<String。索引>在Swift?

我想使用以下UITextFieldDelegate方法:

    func textField(textField: UITextField!,
        shouldChangeCharactersInRange range: NSRange,
        replacementString string: String!) -> Bool {

textField.text.stringByReplacingCharactersInRange(???, withString: string)


当前回答

这与Emilie的回答相似,但是,因为你特别问如何将NSRange转换为Range<String。索引>,你会这样做:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

     let start = advance(textField.text.startIndex, range.location) 
     let end = advance(start, range.length) 
     let swiftRange = Range<String.Index>(start: start, end: end) 
     ...

}

其他回答

Swift 5解决方案

简短的回答带有主要的扩展

extension NSRange {

    public init(range: Range<String.Index>, 
                originalText: String) {

        self.init(location: range.lowerBound.utf16Offset(in: originalText),
                  length: range.upperBound.utf16Offset(in: originalText) - range.lowerBound.utf16Offset(in: originalText))
    }
}

详情请看这里

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
    guard let current = textField.text, let r = Range(range, in: current) else {
        return false
    }
    
    let text = current.replacingCharacters(in: r, with: string)
    // ...
    return true
}

在Swift 2.0中假设func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: string) -> Bool {:

var oldString = textfield.text!
let newRange = oldString.startIndex.advancedBy(range.location)..<oldString.startIndex.advancedBy(range.location + range.length)
let newString = oldString.stringByReplacingCharactersInRange(newRange, withString: string)
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

       let strString = ((textField.text)! as NSString).stringByReplacingCharactersInRange(range, withString: string)

 }
extension StringProtocol where Index == String.Index {

    func nsRange(of string: String) -> NSRange? {
        guard let range = self.range(of: string) else {  return nil }
        return NSRange(range, in: self)
    }
}