Reputation: 905
In text field, I only want to allow 16 characters. I don't want to allow to type over 16 characters. Here is my codes;
let currentCharacterCount = txtPinNo.text?.characters.count ?? 0
if (range.length + range.location > currentCharacterCount){
return false
}
let newLength = currentCharacterCount + string.characters.count - range.length
return newLength <= 19
My Expected Result is --> 1234-1111-3333-6666 (19 characters)
My Actual Outcome Result is --> 1234-1111-2222-4444-4 (the last number always appear, just want to remove "-4")
I don't want to allow to type when over 16 characters. Please help me how to check it.
Upvotes: 0
Views: 475
Reputation: 236340
You can subclass UITextField and create a custom field as follow:
@IBDesignable
class LimitedLengthField: UITextField {
@IBInspectable var maxLength: Int = 16 // set maximum number of characters
var stringValue: String { return text ?? "" }
override func awakeFromNib() {
super.awakeFromNib()
keyboardType = .ASCIICapable // set the keyboard type
addTarget(self, action: #selector(editingChanged), forControlEvents: .EditingChanged)
editingChanged(self)
}
func editingChanged(sender: UITextField) {
sender.text = String(stringValue.characters.prefix(maxLength))
}
}
If you need to ad some custom formatting it would get a little but trickier:
Swift 2
class CustomField: UITextField {
var stringValue: String { return text ?? "" }
var decimalDigits: String {
return stringValue
.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)
.joinWithSeparator("") ?? ""
}
override func awakeFromNib() {
super.awakeFromNib()
addTarget(self, action: #selector(editindChanged(_:)), forControlEvents: .EditingChanged)
keyboardType = .NumberPad
editindChanged(self)
}
func editindChanged(sender: UITextField) {
let letters = Array(decimalDigits.stringByPaddingToLength(16, withString: " ", startingAtIndex: 0).characters)
switch decimalDigits.characters.count {
case 1...4:
text = decimalDigits
case 5...8:
text = (String(letters[0...3]) + "-"
+ String(letters[4...7]))
.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
case 9...12:
text = (String(letters[ 0...3 ]) + "-"
+ String(letters[ 4...7 ]) + "-"
+ String(letters[8...11]))
.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
case 13...16:
text = (String(letters[ 0...3 ]) + "-"
+ String(letters[ 4...7 ]) + "-"
+ String(letters[8...11]) + "-"
+ String(letters[12...15]))
.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
default:
print(text)
if decimalDigits.characters.count > 0 {
text = String(text!.characters.prefix(19))
}
}
}
}
Swift 3
class CustomField: UITextField {
var stringValue: String { return text ?? "" }
var decimalDigits: String {
return stringValue
.components(separatedBy: CharacterSet.decimalDigits.inverted)
.joined(separator: "") ?? ""
}
override func awakeFromNib() {
super.awakeFromNib()
addTarget(self, action: #selector(editindChanged(_:)), for: .editingChanged)
keyboardType = .numberPad
editindChanged(self)
}
func editindChanged(_ sender: UITextField) {
let letters = Array(decimalDigits.padding(toLength: 16, withPad: " ", startingAt: 0).characters)
switch decimalDigits.characters.count {
case 1...4:
text = decimalDigits
case 5...8:
text = (String(letters[0...3]) + "-"
+ String(letters[4...7]))
.trimmingCharacters(in: .whitespaces)
case 9...12:
text = (String(letters[ 0...3 ]) + "-"
+ String(letters[ 4...7 ]) + "-"
+ String(letters[8...11]))
.trimmingCharacters(in:. whitespaces)
case 13...16:
text = (String(letters[ 0...3 ]) + "-"
+ String(letters[ 4...7 ]) + "-"
+ String(letters[8...11]) + "-"
+ String(letters[12...15]))
.trimmingCharacters(in: .whitespaces)
default:
print(text)
if decimalDigits.characters.count > 0 {
text = String(text!.characters.prefix(19))
}
}
}
}
Upvotes: 1