2

a solution to limit the length of a TextField but the function count has been updated, also count() function, so I don't understand how to use this:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let newLength = count(textField.text.utf16) + count(string.utf16) - range.length
    return newLength <= 10 // Bool
}

And how to update this to work on multiple TextField , I think I have to say if

textField = thisTextField.text...
princ___y
  • 1,089
  • 1
  • 9
  • 27
Ben
  • 761
  • 1
  • 12
  • 35

4 Answers4

7

shouldChangeCharactersInRange does the following (Quoted from the docs)

Asks the delegate if the specified text should be changed.

Your added code to this method checks if it exceeds your limit (In your example, it is 10) and returns false which means that the textField should not change values. If it did not exceed the limit, it will return true, and the textField will change values.

To do this for multiple textFields, you will need to have outlets to your multiple textFields, and then a simple if statement inside this method will do the job.

@IBOutlet weak var textfield1: UITextField!
@IBOutlet weak var textfield2: UITextField!

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let newLength = textField.text.characters.count + string.characters.count - range.length
    if textField == textField1 {
        return newLength <= 10 // Bool
    } else if textField == textField2 {
        return newLength <= 15 // Bool
    }

    return true
}

To be able to use the above method in your code, your UIViewController which contains these textFields will need to implement the UITextFieldDelegate protocol, and then by setting the UITextField's delegate property to be that UIViewController.

Also regarding the count method. It has been updated many times. To count the number of characters for a string:

Before Swift1.2 -> countElements(string)
Swift1.2 -> count(string)
Swift2 -> string.characters.count

hannad
  • 822
  • 4
  • 18
  • They're no error but it doesn't work, may I have to add textField1.delegate = self in viewController ? – Ben Dec 22 '15 at 10:36
  • The problem with this answer is that you can't mix Swift `count` with Objective-C `length`, they have two different notions of what constitutes a character. – matt Apr 23 '20 at 14:21
1

From this answer: Set the maximum character length of a UITextField

While the UITextField class has no max length property, it's relatively simple to get this functionality by setting the text field's delegate and implementing the following delegate method:

Objective-C

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    // Prevent crashing undo bug – see note below.
    if(range.length + range.location > textField.text.length)
    {
        return NO;
    }

    NSUInteger newLength = [textField.text length] + [string length] - range.length;
    return newLength <= 25;
}

Swift

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

    let currentCharacterCount = textField.text?.characters.count ?? 0
    if (range.length + range.location > currentCharacterCount){
        return false
    }
    let newLength = currentCharacterCount + string.characters.count - range.length
    return newLength <= 25
}

EDIT

Here is an updated swift method based on the comment.

//  assume you have the following 3 fields
let textField1 = UITextField()
let textField2 = UITextField()
let textField3 = UITextField()

// then declare this dictionary
let lengthsDictionary = [textField1 : 10, textField2: 20, textField3: 30]


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

    guard let length = lengthsDictionary[textField] else {
        return true
    }

    let currentCharacterCount = textField.text?.characters.count ?? 0
    if (range.length + range.location > currentCharacterCount){
        return false
    }
    let newLength = currentCharacterCount + string.characters.count - range.length
    return newLength <= length
}
Community
  • 1
  • 1
mohamede1945
  • 7,092
  • 6
  • 47
  • 61
0

If you want to apply limit on charters for multiple textfields set tag value in IB. For example you have 2 text fields required text limit is 3,4 so set 3 and 4 tag for respective text fields and add below code in shouldChangeCharactersInRange method

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

    let characterCount = textField.text?.characters.count ?? 0
    if (range.length + range.location > characterCount){
        return false
    }
    let newLength = characterCount + string.characters.count - range.length
    return newLength <= textField.tag
}
Narayana Rao Routhu
  • 6,303
  • 27
  • 42
  • I don't understand how to apply this, I have to set the size in the tag ? And how I set different sizes – Ben Dec 22 '15 at 10:39
  • @Ben we have option to set tag for any control from IB itself property call tag. you need set required charter limit value as tag. – Narayana Rao Routhu Dec 22 '15 at 10:50
0
func textField(
    _ textField: UITextField,
    shouldChangeCharactersIn range: NSRange,
    replacementString string: String)
-> Bool {
    
    var currentText = ""
    if textField == passwordTextField{
        currentText = textField.text ?? ""
    } else if textField == againPasswordTextField{
        currentText = textField.text ?? ""
    }

    guard let stringRange = Range(range, in: currentText) else { return false }
    let updatedText = currentText.replacingCharacters(in: stringRange, with: string)
    return updatedText.count <= 6
}

}

Worked for me :)