I have textfield ,shouldChangeCharactersIn codes im using barcode, system and my barcode codes == 12 characters. I want to show only 12 characters in my string if barcode small 12 characters or big must be return false or clean text field . my codes under below. When I using barcode if my barcodes 12 characters working fine , but if I read 12 character low don't clear textfield ,
How can I fix it ?
My codes under below.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let length = (Mytext.text?.characters.count)! - range.length + string.characters.count
if length == 13 {
print("Mytext=\(Mytext.text!)")
Mytext.text = ""
return true
}else {
return true
}
}
Output when read 12 characters barcode shows success !
When read 12 characters low don't clear Mytext field , and when I read again adding +
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if (string != "" && textField.text?.count == 12) {
print("Mytext = \(textField.text!)")
textField.text = ""
return false
}
return true
}
you have to set replacement string to "" blank string
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let length = (Mytext.text?.characters.count)! - range.length + string.characters.count
if length == 13 {
print("Mytext=\(Mytext.text!)")
Mytext.text = ""
return true
}else {
return true
}
}
Related
None of the solutions mentioned here:
How to input currency format on a text field (from right to left) using Swift?
work for me. Please don't mark this as duplicate.
I cannot subclass UITextField to give my own implementation.(This UITextField is also used elsewhere).
The only way that I see is to format replacementText string (user input string) in this method:
override func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let currentText = textField.text ?? ""
var replacementText = (currentText as NSString).replacingCharacters(in: range, with: string)
}
So when user enters a number it should show like this: 0.00.
When the user taps 1. We should have 0.01
When the user taps 2. We should display 0.12
When the user taps 3. We should display 1.23
When the user taps 4. We should display 12.34
private var enteredText: String = ""
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if enteredText.count > 0 && string == "" && range.length == 1 {
//Handles backspace
enteredText.removeLast()
}
else {
enteredText += string
}
return true
}
func textFieldDidChangeCharacter(textField:UITextField) {
if let number = NumberFormatter().number(from: enteredText) {
let double = number.doubleValue/100.0
let string = String(format: "%0.2f", double)
textField.text = string
}
}
I am using phone number texfield, now i am using this format for texfield (#) ### ### ###, now issue is that i want first character 0 as compulsary, like this (0) 959 554 545, so user enter whatever first character must be typed 0,
this is my code
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let newString = textField.text
if ((newString == "") && (newString?.count == 0)){
txtMobileNumber.text = "0"
return true
}else if ((newString?.count)! > 0){
return true
}
return false
}
In shouldChangeCharactersIn method return false if new string count is greater than 15. Else remove (0) and empty spaces, then if the string isn't empty add (0) at the beginning. Then split the string by every 3 characters and join all string with space separator.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
var oldText = (textField.text! as NSString).replacingCharacters(in: range, with: string)
if oldText.count > 15 { return false }
oldText = oldText.replacingOccurrences(of: "(0)", with: "").replacingOccurrences(of: " ", with: "")
if !oldText.isEmpty {
oldText = "(0)" + oldText
}
let newText = String(stride(from: 0, to: oldText.count, by: 3).map {
let sIndex = String.Index(encodedOffset: $0)
let eIndex = oldText.index(sIndex, offsetBy: 3, limitedBy: oldText.endIndex) ?? oldText.endIndex
return String(oldText[sIndex..<eIndex])
}.joined(separator: " "))
textField.text = newText
return false
}
In shouldChangeCharactersIn method of UITextFieldDelegate,
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let text = textField.text {
let str = (text as NSString).replacingCharacters(in: range, with: string).replacingOccurrences(of: "(0)", with: "")
if !str.isEmpty {
textField.text = "(0)" + str
} else {
textField.text = nil
}
}
return false
}
Append (0) to the newly created string, everytime the textField is edited.
If you create Enum, you can choice your textField type and make the extension properties for this field
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
if cellType == .phone {
guard var sanitizedText = textField.text else { return true }
if !sanitizedText.isEmpty && !sanitizedText.hasPrefix("(0)") {
sanitizedText.text = "(0)" + sanitizedText
}
}
}
I have the app for Celectial navigation calculations, I have converted in code textField.text to Double, but some times app crashing if user input some fields like "1.0" and some like "1", in result app crashing because can't deduct Int and Double, to be sure I want to restrict user to input only decimal digits "1.0". The best way for me is to code something like if the user enters for example "1" automatically after pressing the done button, add ".0" to get 1.0?
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let allowedCharacters = "-1234567890."
let allowedCharacterSet = CharacterSet(charactersIn: allowedCharacters)
let typedCharactersSet = CharacterSet(charactersIn: string)
return allowedCharacterSet.isSuperset(of: typedCharactersSet)
}
func TextField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = latDegTextField.text else { return true }
let count = text.count + string.count - range.length
return count == 2
}
First of all use this method from HERE which is
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField.text != "" || string != "" {
let res = (textField.text ?? "") + string
return Double(res) != nil
}
return true
}
And in your done button action add this:
#IBAction func btnDoneTapped(_ sender: Any) {
print(tf.text)
guard let obj = Double(tf.text!) else { return }
print(obj)
}
And when you enter 1 and press done button print(tf.text) will print Optional("1") and print(obj) will print 1.0
Use this code :-
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
//Will prevent user from entering space as first character
let enteredCharString = "\(textField.text ?? "")\(string )"
if enteredCharString.trimmingCharacters(in: .whitespaces).count == 0 {
return false
}
switch textField {
case txt_Ammount:
if txt_Ammount.text != "" || string != "" {
let res = (txt_Ammount.text ?? "") + string
return Double(res) != nil
}
default:
true
}
return true
}
How do we disallow empty input on textField?
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let oldText = textField.text!
let stringRange = Range(range, in:oldText)!
let newText = oldText.replacingCharacters(in: stringRange, with: string)
doneBarButton.isEnabled = !newText.isEmpty
return true
}
Is there other ways? or using other textField delegate methods to do this?
Yes, this is basically how you do it.
Alternatively, if all you want to know if the field is empty or not, just figure out the length of the result:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let length = (textField.text?.count ?? 0) + string.count - range.length
doneBarButton.isEnabled = length > 0
return true
}
You may also want to set enablesReturnKeyAutomatically for the text field to true, so that the keyboard doesn’t enable the “return” key unless there is text in the field.
I am looking to cap the amount of characters a user can type into a textfield at 14. Here is the code that I have found documentation on.
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let currentCharacterCount = userNameTextField.text?.characters.count ?? 0
if (range.length + range.location > currentCharacterCount){
return false
}
let newLength = currentCharacterCount + string.characters.count - range.length
return newLength <= 14
}
but I do not feel that I am implementing this correctly. I have set
userNameTextField.delegate = self
in the viewDidLoad, and I am conforming to the UITextFieldDelegate protocol.
You state you are using Swift 3. The signature of many methods changed in Swift 3. You need to use:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
}
Not the old signature posted in your question.
If it's still not being called, then you never set the text field's delegate property.
Try this instead:
func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool {
let currentString: NSString = (textField.text ?? "") as NSString
let newString = currentString.replacingCharacters(in: range, with: string)
return newString.characters.count <= 14
}
Try this for swift 3:
let limit=4;
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = txtSMSCode.text else { return true }
let newLength = text.characters.count + string.characters.count - range.length
return newLength <= limit
}