UITextField setting maximum character length in Swift
Asked Answered
H

1

1

How can I override this UITextField function so that it will have a limit on the maximum number of characters?

override func shouldChangeText(in range: UITextRange, replacementText text: String) -> Bool {

}

I've done some research on stack, but all I can find is this function (see below). First off, I can't see how this can be an override, and second, it's using NSRange as a parameter where I have UITextRange. How can this be implemented? thanks

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, 
                replacementString string: String) -> Bool {
        let currentString: NSString = textField.text! as NSString
        let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString
        return newString.length <= 4
    }

My failed try:

override func shouldChangeText(in range: UITextRange, replacementText text: String) -> Bool {
        let currentString: NSString = self.text! as NSString
        let newString: NSString = currentString.replacingCharacters(in: range, with: text) as NSString
        return newString.length <= 4
    }

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

Homeward answered 1/10, 2017 at 13:24 Comment(0)
A
2

You can subclass UITextField and add a target for UIControlEvents editingChanged. Inside the selector method you can use collection method prefix to limit the characters added to your textfield text property as follow:

import UIKit
class LimitedLengthField: UITextField {
    var maxLength: Int = 10
    override func willMove(toSuperview newSuperview: UIView?) {
        addTarget(self, action: #selector(editingChanged), for: .editingChanged)
        editingChanged()
    }
    @objc func editingChanged() {
        text = String(text!.prefix(maxLength))
    }
}

You can add your custom text field programatically or using the interface builder:

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let limitedLenghtField = LimitedLengthField(frame: CGRect(origin: CGPoint(x: 50, y: 50), size: CGSize(width: 200, height: 50)))
        limitedLenghtField.text = "123456789012345"
        view.addSubview(limitedLenghtField)
    }
}
Absa answered 1/10, 2017 at 14:3 Comment(4)
interestingly enough, you have also answered another question that I had, which is how to add a function with a parameter in the #selector.Homeward
Which one ? Can you post the link?Absa
your suggestion work fine, I am glad to have an answer that works now. I am however still wondering how to change the code I copied from SO to match the shouldChangeText function in the UITextField class. I guess the only problem I am facing is that one is using the UITextRange and the other is using the NSRange, which don't match. See my failed try in the edit. The error I get is "Cannot convert value of type 'UITextRange' to expected argument type 'NSRange' (aka '_NSRange')"Homeward
sorry, I just saw your comment now. I didn't know about the check mark. I did the check and upvote now thanks.Homeward

© 2022 - 2024 — McMap. All rights reserved.