Search code examples
swiftuitextfieldnsmutableattributedstring

Uneditable prefix inside a UITextField using Swift


I'm having a problem regarding the creation of a prefix inside a UITextField using the new Swift language. Currently I have created the UITextField using the Interface Builder and I have assigned an IBOutlet to it, named usernameField, then using the textFieldDidBeginEditing function I write a NSMutableAttributedString inside it, named usernamePrefix, containing only the word "C-TAD-" and finally I limited the UITextField max characters number to 13, like so:

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var usernameField : UITextField!

    private var usernamePrefix = NSMutableAttributedString(string: "C-TAD-")

    func textFieldDidBeginEditing(textField: UITextField) {
        if textField == usernameField {
            if usernameField.text == "" {
                usernameField.attributedText = usernamePrefix
            }
        }

        usernameField.addTarget(self, action: "textFieldDidChangeText:", forControlEvents:UIControlEvents.EditingChanged)
    }

    func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool {
        let maxUsernameLength = countElements(usernameField.text!) + countElements(string!) - range.length

        return maxUsernameLength <= 13
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        usernameField.delegate = self
        passwordField.delegate = self
    }
}

Now, how can I assign new parameters to the usernamePrefix in order to have to give 2 different colors to the text written in the UITextField? I would like to have the prefix in .lightGreyColor() and the rest in .blackColor(). Also how can I make the usernamePrefix un-editable and un-deletable by the user?

Thanks for the help


Solution

  • For the first part, you can refactor your delegate method as follow.

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        //This makes the new text black.
        textField.typingAttributes = [NSForegroundColorAttributeName:UIColor.blackColor()]
        let protectedRange = NSMakeRange(0, 6)
        let intersection = NSIntersectionRange(protectedRange, range)
        if intersection.length > 0 {
    
            return false
        }
        if range.location == 12 {
            return true
        }
        if range.location + range.length > 12 {
            return false
        }
        return true
    }
    

    This will lock down both the length at 13 and the prefix can not be deleted. Everything typed will be UIColor.blackColor()

    Then you can a method like the following in your viewDidLoad, to set the prefix.

    func makePrefix() {
        let attributedString = NSMutableAttributedString(string: "C-TAD-")
        attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.lightGrayColor(), range: NSMakeRange(0,6))
        textField.attributedText = attributedString
    }