Marco Almeida
Marco Almeida

Reputation: 1303

How to prevent empty or whitespaces in UITextField in Swift?

I am trying to prevent a UITextField from being entered space character or no character, but works only for no character. What I need is: the user is not allowed to save textfield without inputing any character and also just spaces; But the user can input, for example: "New Category". So spaces are only allowed between letters or number, but not only spaces.

Here´s my code:

@IBAction func btnAddCategory(sender: AnyObject) {
    let alert = UIAlertController(title: "Ajouter une catégorie", message: nil, preferredStyle: .Alert)
    alert.view.tintColor = Utils.colorFromHex(0x585858)
    let confirmAction = UIAlertAction(title: "OK", style: .Default, handler: ({ (_) in
        if let field = alert.textFields?[0] {
            if field.text! == NSCharacterSet.whitespaceCharacterSet() || field.text! == ""{
                self.displayAlert("Attention", alertMsg: "Vous ne pouvez pas créer des données vides")
            } else {
                if self.checkDuplicates(field.text!) {
                    self.displayAlert("Attetion", alertMsg: "Vous avez déjà une catégorie avec ce nom !")
                } else {
                    self.saveCategory(field.text!)
                    self.tableView.reloadData()
                }
            }
        }
        }
    ))

    let cancelAction = UIAlertAction(title: "Annuler", style: .Cancel, handler: nil)

    alert.addTextFieldWithConfigurationHandler({(textField) in
        textField.placeholder = "Titre"
        textField.font = UIFont(name: "Roboto-Light", size: 15)!
    })

    alert.addAction(confirmAction)
    alert.addAction(cancelAction)

    self.presentViewController(alert, animated: true, completion: nil)
}

So anyone could help me on this?

Upvotes: 2

Views: 9926

Answers (4)

Friend
Friend

Reputation: 125

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

        let   trimmedString = string.trimmingCharacters(in: .whitespacesAndNewlines)
        var subString = textField.text as NSString?
        subString = subString?.replacingCharacters(in: range, with: string) as NSString?

        if (textField.tag == 0 || textField.tag == 1)
        {
            let acceptedInput = NSCharacterSet.alphanumerics.inverted
            let filteredString = (trimmedString.components(separatedBy: acceptedInput)).joined(separator: "")

            if trimmedString == filteredString
            {
                textField.text = (textField.text! as NSString).replacingCharacters(in: range, with: filteredString)

                return false
            }
            else
            {
                return false
            }
        }
        return true

    }

Upvotes: 1

Kedar Sukerkar
Kedar Sukerkar

Reputation: 1565

Swift 5.1, Xcode 11

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard range.location == 0 else {
        return true
    }

    let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string) as NSString
    return newString.rangeOfCharacter(from: CharacterSet.whitespacesAndNewlines).location != 0
}

Upvotes: 2

Marco Almeida
Marco Almeida

Reputation: 1303

Finally managed to get it fixed with this code:

@IBAction func btnAddCategory(sender: AnyObject) {
    let alert = UIAlertController(title: "Ajouter une catégorie", message: nil, preferredStyle: .Alert)
    alert.view.tintColor = Utils.colorFromHex(0x585858)
    let confirmAction = UIAlertAction(title: "OK", style: .Default, handler: ({ (_) in
        if let field = alert.textFields?[0] {

            let strLength = field.text!.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()).characters.count

            if  strLength == 0 {
                self.displayAlert("Attention", alertMsg: "Vous ne pouvez pas créer des données vides")
            } else {
                if self.checkDuplicates(field.text!) {
                    self.displayAlert("Attetion", alertMsg: "Vous avez déjà une catégorie avec ce nom !")
                } else {
                    self.saveCategory(field.text!)
                    self.tableView.reloadData()
                }
            }
        }
        }
    ))

    let cancelAction = UIAlertAction(title: "Annuler", style: .Cancel, handler: nil)

    alert.addTextFieldWithConfigurationHandler({(textField) in
        textField.placeholder = "Titre"
        textField.font = UIFont(name: "Roboto-Light", size: 15)!
    })

    alert.addAction(confirmAction)
    alert.addAction(cancelAction)

    self.presentViewController(alert, animated: true, completion: nil)
}

Upvotes: 1

Andrea
Andrea

Reputation: 26385

If you want to prevent white spaces while digiting characters, you can implement the textfield(textfield:UITextField, shouldChangeCharactersInRange: NSRange, replacementString: String) -> Bool delegate method of UITexfieldDelegate protocol.
In the implementation you should return false if the the new character is a space or true for something else.
What we are doing here is creating a set of characters to check against.
NSCharacterSet provides already different sets.

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        let inValidCharacterSet = NSCharacterSet.whitespaceCharacterSet()
        guard let firstChar = string.unicodeScalars.first else {return true}
        return !inValidCharacterSet.isCharInSet(Character(firstChar))
    }

Where isCharInSet is an extension of NSCharacterSet (I've taken and modified that method from somewhere in S.O.):

extension NSCharacterSet {
    func isCharInSet(char: Character) -> Bool {
        var found = true
        for ch in String(char).utf16 {
            if !characterIsMember(ch) { found = false }
        }
        return found
    }
}

Upvotes: 3

Related Questions