在Swift中使用stringByReplacingCharactersInRange

时间:2014-06-03 12:58:48

标签: swift

我正在尝试在Swift / Xcode6中使用UITextFieldDelegate,我正在努力使用我应该使用stringByReplacingCharactersInRange的方式。编译器错误是“无法将表达式的类型'String'转换为'$ T8'。

func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool
{
    let s = textField.text.stringByReplacingCharactersInRange(range:range, withString:string)
    if countElements(s) > 0 {

    } else {

    }
    return true
}

Xcode 6 Beta 5的更新:事情是shouldChangeCharactersInRange给出一个NSRange对象,我们需要一个Swift Range对象用于stringByReplacingCharactersInRange。这仍然可以被认为是一个错误,因为我不明白为什么我们仍然应该处理NS *对象?委托方法的String参数无论如何都是Swift类型。

13 个答案:

答案 0 :(得分:25)

这里是如何计算各种Swift版本中的结果字符串。

请注意,所有方法都以完全相同的方式使用-[NSString stringByReplacingOccurrencesOfString:withString:],只是语法不同。

这是计算结果字符串的首选方法。转换为Swift Range并在Swift String上使用它很容易出错。例如,当使用非ASCII字符串操作时,Johan的答案在某些方面是不正确的。

Swift 3:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let result = (textField.text as NSString?)?.replacingCharacters(in: range, with: string) ?? string
    // ... do something with `result`
}

Swift 2.1:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let result = (textField.text as NSString?)?.stringByReplacingCharactersInRange(range, withString: string)
    // ... do something with `result`
}

Swift 1(仅留待此处参考):

let result = textField.text.bridgeToObjectiveC().stringByReplacingCharactersInRange(range, withString:string)

答案 1 :(得分:17)

我创建了转化为NSRange

Range<String.Index>扩展程序
extension NSRange {
    func toRange(string: String) -> Range<String.Index> {
        let startIndex = advance(string.startIndex, location)
        let endIndex = advance(startIndex, length)
        return startIndex..<endIndex
    }
}

所以我可以像这样创建String

let text = textField.text
let newText = text.stringByReplacingCharactersInRange(range.toRange(text), withString: string)
在Swift 2.1中的

扩展名如下:

extension NSRange {
    func toRange(string: String) -> Range<String.Index> {
        let startIndex = string.startIndex.advancedBy(location)
        let endIndex = startIndex.advancedBy(length)
        return startIndex..<endIndex
    }
}

答案 2 :(得分:15)

我发现最简单的解决方案是使用as NSString - 这使我们能够使用NSRange

var textField : UITextField = UITextField()
textField.text = "this is a test"

let nsRange : NSRange = NSRange(location: 0, length: 4)

let replaced = (textField.text as NSString)
               .stringByReplacingCharactersInRange(nsRange, withString: "that");

NSLog("Replaced: %@", replaced); //prints "that is a test"

答案 3 :(得分:7)

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

bridgeToObjectiveC可以在即将到来的更新中删除

答案 4 :(得分:6)

除了以下内容之外,没有什么对我有用:(仅供参考我使用 Xcode7.0 GM Swift 2.0 iOS9GM

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let currentText = textField.text ?? ""
    let prospectiveText = (currentText as NSString).stringByReplacingCharactersInRange(range, withString: string)
    print("prospectiveText", prospectiveText)
    return true;
}

答案 5 :(得分:2)

这是来自this question的交叉帖子,但没有办法让Range<String.Index> Swift-native String.stringByReplacingCharactersInRange()毫无用处。所以,这是一个生成Range<String.Index>

的函数
func RangeMake(#start:Int, #end:Int) -> Range<String.Index> {
    assert(start <= end, "start must be less than or equal to end")
    func rep(str: String, count: Int) -> String {
        var result = ""
        for i in 0..count {
            result += str
        }
        return result
    }
    let length = end - start
    let padding = rep(" ", start)
    let dashes = rep("-", length)
    let search = padding + dashes
    return search.rangeOfString(dashes, options: nil, range: Range(start: search.startIndex, end: search.endIndex), locale: NSLocale.systemLocale())
}

let sourceString = "Call me Ishmael."
let range = RangeMake(start: 8, end: 15)    
let name = sourceString.substringWithRange(range)
// name = "Ishmael"

答案 6 :(得分:1)

创建String.Index非常麻烦。

let string = "hello"
let range = string.startIndex .. string.startIndex.succ().succ()
let result = string.stringByReplacingCharactersInRange(range, withString: "si")

答案 7 :(得分:1)

for iOS 8.3使用以下代码

 func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
    if textField.isEqual(<textField whose value to be copied>)
    {
        <TextField to be updated>.text = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
    }

    return true
}

答案 8 :(得分:1)

从Swift 4开始,这比Alexander Volkov的答案要简单一些,但没有扩展名。

   func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let revisedText: String
        if let text = textField.text, let swiftRange = Range(range, in: text) {
            revisedText = text.replacingCharacters(in: swiftRange, with: string)
        } else {
            revisedText = string
        }
        // Do something with the text and return boolean.
   }

答案 9 :(得分:0)

import UIKit

class LoginViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var submitButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }



    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        let length = count(textField.text) - range.length + count(string)
        if length > 0 {
            submitButton.enabled = true
        } else {
            submitButton.enabled = false
        }
        return true
    }
}

答案 10 :(得分:0)

使用Swift 2.0时,必须更改Durul的答案,因为必须使用characters.count而不是count()。

必须完成以下操作。

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let length = textField.text!.characters.count - range.length + string.characters.count
    if length > 0 {
        submitButton.enabled = true
    } else {
        submitButton.enabled = false
    }
    return true
}

答案 11 :(得分:0)

Swift 4:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    var text = textField.text ?? ""
    text.replaceSubrange(range.toRange(string: text), with: string)
    ...
    return true
}

extension NSRange {

    /// Convert to Range for given string
    ///
    /// - Parameter string: the string
    /// - Returns: range
    func toRange(string: String) -> Range<String.Index> {
        let range = string.index(string.startIndex, offsetBy: self.lowerBound)..<string.index(string.startIndex, offsetBy: self.upperBound)
        return range
    }
}

答案 12 :(得分:0)

工作&amp;测试

main