在键入和保留光标位置时强制UITextField为小写

时间:2016-02-22 08:10:12

标签: ios swift2 xcode7

(在swift 2中编程)

我有一个UITextField,当用户输入它时,应该自动转换为小写的WHILE键入(所以不要在表单验证后)。

我已经走到了这一步:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    //only convert to lowercase for username field
    if textField == textFieldUsername {
        //let stringRange = NSRange(location: range.location, length: range.length)
        let completedString = (textField.text ?? "" as NSString).stringByReplacingCharactersInRange(range, withString: string)
        //convert the while thing to lowercase and assign back to the textfield
        textField.text = completedString.lowercaseString
        //return false to indicate that the "system" itself should not do anychanges anymore, as we did them
        return false
    }
    //return to the "system" that it can do the changes itself
    return true
}

问题是(1)当用户按下并保持在UITextField上时(2)将光标移动到字符串中间的某个位置并且(3)开始键入(4)光标跳回到结束时已输入字符串。

在调用textField:shouldChangeCharactersInRange后,是否需要恢复光标位置?

4 个答案:

答案 0 :(得分:4)

我已经接受了你的代码并尝试了这个。

我可以在文本被更改的地方替换光标位置。

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

    let start = textField.positionFromPosition(textField.beginningOfDocument, offset:range.location)

    let cursorOffset = textField.offsetFromPosition(textField.beginningOfDocument, toPosition:start!) + string.characters.count


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

    let newCursorPosition = textField.positionFromPosition(textField.beginningOfDocument, offset:cursorOffset)

    let newSelectedRange = textField.textRangeFromPosition(newCursorPosition!, toPosition:newCursorPosition!)

    textField.selectedTextRange = newSelectedRange

    return false
}

答案 1 :(得分:3)

Swift 4

lowercaseString已更改为lowercased()。如果您愿意,也可以通过目标操作而不是NotificationCenter来执行此操作。

@IBOutlet fileprivate weak var textField: UITextField!

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    textField.addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged)
}

@objc func textFieldDidChange(textField: UITextField) {
    textField.text = textField.text?.lowercased()
} 

答案 2 :(得分:2)

更简单的方法就是这样。

  1. 注册UITextFieldTextDidChangeNotification

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "textFieldDidChange:", name: UITextFieldTextDidChangeNotification, object: textField)

  2. 更改通知回调中的案例。

    func textFieldDidChange(notification:NSNotification) { textField.text = textField.text?.lowercaseString }

答案 3 :(得分:1)

使用RxSwift 4.0的解决方案:

只需称呼它:

emailField.rx.controlEvent(.editingChanged)
    .asObservable()
    .subscribe(self.onEditingChanged)
    .disposed(by: self.disposeBag)

通过此回调:

private func onEditingChanged(event : Event<Void>){
    self.emailField.text = self.emailField.text?.lowercased()
}