Set UITextField to mm-dd-yy format in swift - ios

So I want to have a UITextField to only accept digits, solved that by using a custom keyboard input.
The intention of this UITextField is to get someones birthday. I don't want to use an UIDatePicker tough as I don't like it's appearance.
I'd like that the TextField automatically inserts dashes after every second digit that the user put into the TextField.
dd-mm-yy is the placeholder text. I either thought of making the dashes permanently but I don't know how to do that either.
How can I do this?

You want to allow user to enter text in textfield in this dd-mm-yy right ?
if it so i'am sure this will help you.
In top of your class declare this variable which we gonna use later.
var dateFormate = Bool()
Add delegate and tag for that textfield.
Then add this following delegate method
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
//1. To make sure that this is applicable to only particular textfield add tag.
if textField.tag == 1 {
//2. this one helps to make sure that user enters only numeric characters and '-' in fields
let numbersOnly = NSCharacterSet(charactersInString: "1234567890-")
let characterSetFromTextField = NSCharacterSet(charactersInString: string)
let Validate:Bool = numbersOnly .isSupersetOfSet(characterSetFromTextField)
if !Validate {
return false;
}
if range.length + range.location > textField.text?.characters.count {
return false
}
let newLength = (textField.text?.characters.count)! + string.characters.count - range.length
if newLength == 3 || newLength == 6 {
let char = string.cStringUsingEncoding(NSUTF8StringEncoding)!
let isBackSpace = strcmp(char, "\\b")
if (isBackSpace == -92) {
dateFormate = false;
}else{
dateFormate = true;
}
if dateFormate {
let textContent:String!
textContent = textField.text
//3.Here we add '-' on overself.
let textWithHifen:NSString = "\(textContent)-"
textField.text = textWithHifen as String
dateFormate = false
}
}
//4. this one helps to make sure only 8 character is added in textfield .(ie: dd-mm-yy)
return newLength <= 8;
}
return true
}
That's it now user can enter their DOB.No need to worry about '-' it will be added automatically.
Swift 3:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
//1. To make sure that this is applicable to only particular textfield add tag.
if textField.tag == 1 {
//2. this one helps to make sure that user enters only numeric characters and '-' in fields
let numbersOnly = CharacterSet(charactersIn: "1234567890-")
let Validate = string.rangeOfCharacter(from: numbersOnly.inverted) == nil ? true : false
if !Validate {
return false;
}
if range.length + range.location > textField.text?.characters.count {
return false
}
let newLength = (textField.text?.characters.count)! + string.characters.count - range.length
if newLength == 3 || newLength == 6 {
let char = string.cString(using: NSUTF8StringEncoding)!
let isBackSpace = strcmp(char, "\\b")
if (isBackSpace == -92) {
dateFormate = false;
}else{
dateFormate = true;
}
if dateFormate {
let textContent:String!
textContent = textField.text
//3.Here we add '-' on overself.
let textWithHifen:NSString = "\(textContent)-"
textField.text = textWithHifen as String
dateFormate = false
}
}
//4. this one helps to make sure only 8 character is added in textfield .(ie: dd-mm-yy)
return newLength <= 8;
}
return true
}

Swift5
// Use textfield delegate shouldChangeCharactersIn
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if (textField.text?.count == 2) || (textField.text?.count == 5) {
if !(string == "") {
textField.text = (textField.text)! + "-"
}
}
return !(textField.text!.count > 7 && (string.count ) > range.length)
}

Related

Issue with restrict limit characters & restrict special charecters in swift?

I am creating a OTP Screen on that screen i have added 6 text fields.Now i want to restrict to enter only ONE charecter & also want to restrict user not to enter any special charecters.Below is the code i have used,Please review the code & let me know what is wrong ?
let notAllowedCharacters = "!##$%^&*()_+{},./[]?:;";
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,replacementString string: String) -> Bool
{
guard let text = textField.text else { return true }
let newLength = text.characters.count + string.characters.count - range.length
if newLength <= 1 {
return true
}
else {
let set = NSCharacterSet(charactersIn: notAllowedCharacters);
let filtered = string.components(separatedBy: set as CharacterSet).joined(separator: "")
return filtered == string;
}
}
You need to add the control of your NSCharacterSet when you make the check for the characters length. Otherwise it will always be true regardless character if there is always one character. Update your code to the following and it will work for you:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,replacementString string: String) -> Bool {
guard let text = textField.text else { return true }
let newLength = text.characters.count + string.characters.count - range.length
let set = NSCharacterSet(charactersIn: notAllowedCharacters)
if newLength <= 1 && !(string.rangeOfCharacter(from: set as CharacterSet) != nil) {
return true
} else {
return false
}
}

Deleting Emoji Bug

I followed this link Find out if Character in String is emoji? to try to limit the amount of characters my text field even with emojis. According to this link, I have to count emojis based on their glyphs and everything is working except for one little bug, when my glyph count is reached, it won't let me delete the string anymore.
Here's the code the handle the character limit using UITextField Delegate
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
var canEditString : Bool = false
if textField == self.descTxtField {
// Description Text Field
if textField.text != nil || textField.text != "" {
let currentString = textField.text
if (currentString?.containsEmoji)! {
print("I have an emoji")
let glyphCount = currentString!.glyphCount
print(glyphCount)
canEditString = glyphCount <= descriptionLimit
}else {
print("I have no emoji's")
let currentCharacterCount = textField.text?.characters.count ?? 0
//print(currentCharacterCount)
if (range.length + range.location > currentCharacterCount){
return false
}
let newLength = currentCharacterCount + string.characters.count - range.length
canEditString = newLength <= descriptionLimit
}
}
return canEditString
} else {
// Number Text Field
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 <= numberLimit
}
}
String Manifesto
Swift 4
Emojis now have a character count of 1, making it a lot easier to keep track of character counts in Strings.

Using `textField:shouldChangeCharactersInRange:`, how do i found that characters are mismatch?

I'm using the code below for setting validation of textfield as it should not enter above 15 character length .
let limitLength = 15
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// set maximum length for password and confirm password
if textField == txtPassword { // if textfield password is editing
guard let text = textField.text else { return true }
let newLength = text.characters.count + string.characters.count - range.length
return newLength <= limitLength
} else if textField == txtConfirmpassword { // if textfield confirm password is editing
guard let text = textField.text else { return true }
let newLength = text.characters.count + string.characters.count - range.length
return newLength <= limitLength
}
return true
}
there are two textfield as password and confirm password
i want to check validation whether they have same string or not?
"textField:shouldChangeCharactersInRange" is method we need to use but i don't know how to compare while user is entering and i need to display alert message that they are not same
Note :- it should not compare while click on any button.
try like this
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// set maximum length for password and confirm password
if textField == txtPassword { // if textfield password is editing
guard let text = textField.text else { return true }
let newLength = text.characters.count + string.characters.count
return newLength <= limitLength
} else if textField == txtConfirmpassword { // if textfield confirm password is editing
guard let text = textField.text else { return true }
let newLength = text.characters.count + string.characters.count
if newLength <= limitLength && txtPassword.text.hasPrefix("\(text)\(string)") {
return true
} else {
// here u can show alert
textField.resignFirstResponder()
return false
}
}
return true
}

How do I limit text lengths for different UITextFields in Swift?

I have an iOS Xcode 7.3 Swift2 project I'm working on. It has different UITextFields that are limited to 3 digits, specifically only numbers. They are assigned to the UITextFieldDelegate and it's working well.
Here is where I limit them:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
guard let text = textField.text else { return true }
let newLength = text.characters.count + string.characters.count - range.length
let limitLength = 3
if newLength > limitLength {
return false
}
let numberOnly = NSCharacterSet.init(charactersInString: "0123456789")
let stringFromTextField = NSCharacterSet.init(charactersInString: string)
let strValid = numberOnly.isSupersetOfSet(stringFromTextField)
return strValid
}
However, some of the UITextFields need to be limited to numbers still AND also limited to a single digit, how can I institute this in the section above, only for those specific UITextFields?
The names of the UITextFields that need to be single digits are:
widthInches
lengthInches
I tried placing this after the first guard section with no luck:
guard let text2 = widthInches.text else { return true }
let newLength2 = text2.characters.count + string.characters.count - range.length
let limitLength2 = 3
if newLength2 > limitLength2 {
return false
}
You can also try this code for limit textfield
actually i am using here textfield tag. Because custom textfield.
If you using custom textfield like TextfieldEffect in this condition tag will help you for limit of Textfield.
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool{
if textField.tag == txtCountryCode.tag{
let maxLength = 4
let currentString: NSString = textField.text!
let newString: NSString =
currentString.stringByReplacingCharactersInRange(range, withString: string)
return newString.length <= maxLength
}
if textField.tag == txtMobileNumber.tag{
let maxLength = 10
let currentString: NSString = textField.text!
let newString: NSString =
currentString.stringByReplacingCharactersInRange(range, withString: string)
return newString.length <= maxLength
}
return true
}
I hope this will help you.
The function shouldChangeCharactersInRange passes in the particular textField as one of its parameters. You can look at that and see if it points to the same instance as the ones you want to shorten, like this:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
guard let text = textField.text else { return true }
var limitLength = 3
if textField == widthInches || textField == lengthInches {
limitLength = 1
}
let newLength = text.characters.count + string.characters.count - range.length
if newLength > limitLength {
return false
}
let numberOnly = NSCharacterSet.init(charactersInString: "0123456789")
let stringFromTextField = NSCharacterSet.init(charactersInString: string)
let strValid = numberOnly.isSupersetOfSet(stringFromTextField)
return strValid
}
Assuming all other requirements are the same (numbers only) this will do the trick.
There are other ways, for example - you could subclass UITextField and add a limitLength field, then use that field in the delegate, but that's probably overkill for just 2 exceptions.
Hello in your func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool the textField param is the textField that has trigger this event so you can check with yours textfields objects and if are equal to one of them then make a different behavior
I hope this helps you,
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
return (textField.text?.utf16.count ?? 0) + string.utf16.count - range.length <= TEXT_FIELD_LIMIT
}
This counts the number of characters based on UTF-16 representation, as range.length is given in UTF-16 base. If you need to count the number of characters in other ways, the expression may get longer. If you want only numbers to be input use textField.keyboardType = UIKeyboardTypeDecimalPad . If you want specific textFields then add tags and compare them and if they are equal you can implement your specific code for that.
Check this link for detailed answer :
http://www.globalnerdy.com/2016/05/24/a-better-way-to-program-ios-text-fields-that-have-maximum-lengths-and-accept-or-reject-specific-characters/
update for swift 3 add this class and call it TextField.swift. it will add the limit input on the storyboard.
import UIKit
private var maxLengths = [UITextField: Int]()
extension UITextField {
#IBInspectable var maxLength: Int {
get {
guard let length = maxLengths[self] else {
return Int.max
}
return length
}
set {
maxLengths[self] = newValue
// Any text field with a set max length will call the limitLength
// method any time it's edited (i.e. when the user adds, removes,
// cuts, or pastes characters to/from the text field).
addTarget(
self,
action: #selector(limitLength),
for: UIControlEvents.editingChanged
)
}
}
func limitLength(textField: UITextField) {
guard let prospectiveText = textField.text,
prospectiveText.characters.count > maxLength else {
return
}
// If the change in the text field's contents will exceed its maximum
length,
// allow only the first [maxLength] characters of the resulting text.
let selection = selectedTextRange
// text = prospectiveText.substring(with:Range<String.Index>
(prospectiveText.startIndex ..< prospectiveText.index(after: maxLength))
let s = prospectiveText
// Get range 4 places from the start, and 6 from the end.
let c = s.characters;
let r = c.index(c.startIndex, offsetBy: 0)..<c.index(c.endIndex, offsetBy: maxLength - c.count)
text = s[r]
// Access the string by the range.
selectedTextRange = selection
}
}
or download here - >TextField.swift

How to limit length of input of Textfield - Swift 2

This code works perfectly, and I can't key in anything other than integers, even when I try to paste it in.
I'd like to add one more refinement, which is to limit the length of the input. Here's my code:
func initializeTextFields()
{
APTeams.delegate = self
APTeams.keyboardType = UIKeyboardType.NumberPad
APRounds.delegate = self
APRounds.keyboardType = UIKeyboardType.NumberPad
APBreakers.delegate = self
APBreakers.keyboardType = UIKeyboardType.NumberPad
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// Find out what the text field will be after adding the current edit
let text = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)
if text == "" {
return true
}
if let _ = Int(text) {
return true
}
else {
return false
}
}
What do I have to add to it to achieve this? The maximum input length for all the TextFields should be <= 4.
BTW, all code is in Swift 2. From problems I faced when trying to implement answers to questions I've asked before, I gather that some of the methods are different.
count(textField.text) is deprecated in SWIFT 2.0
public func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if let textField = textField as? UITextField {
if (range.length + range.location > textField.text!.characters.count) {
return false;
}
let newLength = textField.text!.characters.count + string.characters.count - range.length;
switch(textField.tag) { //In case you want to handle multiple textfields
case Constants.TAG1:
return newLength <= 20;
case Constants.TAG2:
return newLength <= 30;
default:
return newLength <= 15;
}
}
return true;
}
Write the condition in textfield delegate method as:-
func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool {
if (count(textField.text) > 4 && range.length == 0)
{
return false // return NO to not change text
}
else
{
}
write all your code part in else part.
The delegate methods or an NSFormatter such as NSNumberFormatter.
The formatter is the most appropriate generally as it also provides localization support.
I know its bit too late but still I want share it too, I found a way which is much easier to set a limit character for an textfield in swift development.
Here is the code:-
import UIKit
private var maxLengths = [UITextField: Int]()
extension UITextField {
#IBInspectable var maxLength: Int {
get {
guard let length = maxLengths[self] else {
return Int.max
}
return length
}
set {
maxLengths[self] = newValue
addTarget(self, action: #selector(limitLength), for: .editingChanged)
}
}
#objc func limitLength(textField: UITextField) {
guard let prospectiveText = textField.text, prospectiveText.count > maxLength else {
return
}
let selection = selectedTextRange
let maxCharIndex = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
#if swift(>=4.0)
text = String(prospectiveText[..<maxCharIndex])
#else
text = prospectiveText.substring(to: maxCharIndex)
#endif
selectedTextRange = selection
}
}
and just set the limit through the panel.
Image:
Just try this to limit the length of TF
Editing changed Action Outlet of TF
#IBAction func otpTF2EditingChnaged(_ sender: UITextField) {
if (sender.text?.count == 1) {
otpTF3.becomeFirstResponder()
}
checkMaxLength(textField: sender , maxLength: 1)
}
Function That will limit the length
private func checkMaxLength(textField: UITextField!, maxLength: Int) {
if (textField.text!.count > maxLength) {
textField.deleteBackward()
}
}

Resources