UITextField Delegate method doesn't get triggered - swift

I am trying to limit the number of characters that the user can enter to 1.
class ActivationViewController: UIViewController , UITextFieldDelegate{
#IBOutlet weak var activationCodeTextField1: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.activationCodeTextField1.addTarget(self, action: #selector(self.textField1DidChange(_:)), for: UIControl.Event.editingChanged)
self.activationCodeTextField1.delegate = self
}
#IBAction func textField1DidChange(_ sender: AnyObject) {
print("TextField1DidChange")
}
func activationCodeTextField1(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// You can check for other things besides length here as well.
print("isValidLength: ", isValidLength(textField: activationCodeTextField1, range: range, string: string))
return isValidLength(textField: activationCodeTextField1, range: range, string: string)
}
private func isValidLength(textField: UITextField, range: NSRange, string: String) -> Bool {
let length = ((textField.text ?? "").utf16).count + (string.utf16).count - range.length
return length <= 1
}
}
However, the function activationCodeTextField1 doesn't get triggered and this line inside of it doesn't print anything:
print("isValidLength: ", isValidLength(textField: activationCodeTextField1, range: range, string: string))
Any idea what I've done wrong?

You can't change the name of delegate methods. The correct function is
optional func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool
Documentation

You have not called any of the method from UITextFieldDelegate protocol. Please checkout link to find methods in UITextFieldDelegate protocol.
https://developer.apple.com/documentation/uikit/uitextfielddelegate

Related

Why does text field content always start with a capital letter? [duplicate]

I would like to force lowercase in an UITextfield when the user is typing.
I came out so far with this code, but seems like it's not lowering characters.
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if string.characters.count == 0 {
return true
}
let currentText = textField.text ?? ""
let prospectiveText = (currentText as NSString).stringByReplacingCharactersInRange(range, withString: string.lowercaseString)
switch textField {
// Allow only lower-case vowels in this field,
// and limit its contents to a maximum of 6 characters.
case userNameTextField:
return prospectiveText.characters.count <= 27
default:
return true
}
}
First you should set following property on your textfield to restrict auto capitalisation:
textfield.autocapitalizationType = UITextAutocapitalizationType.None
And this is how you can restrict it further:
func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool {
if let _ = string.rangeOfCharacterFromSet(NSCharacterSet.uppercaseLetterCharacterSet()) {
// Do not allow upper case letters
return false
}
return true
}
UPDATED FOR SWIFT 4
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let _ = string.rangeOfCharacter(from: .uppercaseLetters) {
// Do not allow upper case letters
return false
}
return true
}
You could do like this and lowercase the entire string when something has changed.
textfield.addTarget(self, action: "textViewChanged", forControlEvents: .EditingChanged);
func textViewChanged(){
textfield.text = textfield.text?.lowercaseString;
}
for swift 3 users, the above code given by Abhinav is just converted to the following
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let _ = string.rangeOfCharacter(from:NSCharacterSet.uppercaseLetters) {
return false
}
return true
}
if you want to convert all input characters to lower case you should do this code:
Swift 4:
in override func viewDidLoad() add this:
textfield.addTarget(self, action: #selector(self.textFieldDidChange(_:)), for: UIControlEvents.editingChanged)
and then add this function to your class:
#objc func textFieldDidChange(_ textField: UITextField) {
if let text:String = textfield.text {
DispatchQueue.main.async {
self.textfield.text = text.lowercased()
}
}
}
it is necessary to change it in main thread.

How do you set a maximum number value for a textfield in Swift that's flexible?

I would like to use the
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
}
I'm fetching a number from firebase which will be the maximum they will be allowed to type into a textfield. Fetching the number is easy, how do I set this maximum for the UITextField?
Just make a class and fill maximum number in storyboard as like:
import UIKit
#IBDesignable
class CustomTextField: UITextField {
#IBInspectable var maxLength: Int = Int.max {
didSet {
addTarget(self, action: #selector(limitLength), for: .editingChanged)
}
}
override func didMoveToWindow() {
super.didMoveToWindow()
addTarget(self, action: #selector(limitLength), for: .editingChanged)
}
#objc private func limitLength() {
guard let prospectiveText = text, prospectiveText.count > maxLength else {
return
}
let selection = selectedTextRange
text = String(prospectiveText.prefix(maxLength))
selectedTextRange = selection
}
}
you can use textField value;
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField.text.count <= maximumNumberOfCharachters {
...
}
return false
}

Swift - How to limit the a few specific text field only allow to insert int?

How to limit the few specific text field only allow to insert int?
not all text fields. only a few specific ones.
Thank you.
Try this one.
class ViewController: UIViewController,UITextFieldDelegate {
#IBOutlet var yourTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
yourTextField.delegate = self
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
//For mobile numer validation
if textField == yourTextField {
//Add specific int numbers
let allowedCharacters = CharacterSet(charactersIn:"0123 ")//Here change this characters based on your requirement
let characterSet = CharacterSet(charactersIn: string)
return allowedCharacters.isSuperset(of: characterSet)
}
return true
}
}
Tried setting your textField's keyboard type?
yourTextField.keyboardType = .numberPad
Can also look into the delegate method
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return true
}
You can from there add logic to return true or false if the textField's selection meets your requirements

textfield extension is not updating text on screen (swfit4)

The extension code below updates the the text but does not update the last letter. So if the word she is type in the textfield the text on the screen only shows sh.
extension ViewController: UITextFieldDelegate{
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
DispatchQueue.main.async {
self.textNode.textGeometry.string = textField.text!
}
return true
}
}
I believe that you need to make your delegate callback like this:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let textEntered = textField.text,
let textRange = Range(range, in: textEntered) {
let updatedText = textEntered.replacingCharacters(in: textRange, with: string)
print("User Has Entered \(updatedText)")
DispatchQueue.main.async {
self.textNode.textGeometry.string = updatedText
}
}
return true
}
Hope it helps...

textField method of UITextFieldDelegate not being called

I think I'm probably doing something stupid but I'm going to ask the question anyway.
I cannot see the UITextFieldDelegate method textField being called. I've created a simple program with print statements showing all other delegate methods get called okay, but not this one. Here's the program code:
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
//MARK: Properties
#IBOutlet weak var testTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
testTextField.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: UITextFieldDelegate
func textFieldShouldReturn(textField: UITextField) -> Bool {
print("textFieldShouldReturn")
textField.resignFirstResponder()
return true
}
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
print("textFieldShouldBeginEditing")
return true
}
func textFieldDidBeginEditing(textField: UITextField) {
print("textFieldDidBeginEditing")
print("Leaving textFieldDidBeginEditing")
}
func textField(textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
print("textField")
print("Leaving textField")
return true
}
func textFieldDidEndEditing(textField: UITextField) {
print("textFieldDidEndEditing")
print("textField = \(textField.text)")
print("Leaving textFieldDidEndEditing")
}
}
Ands that's it. I have a ViewController with a UITextField added in Interface Builder. Entering text shows the other delegate methods are being called okay. I'm using Xcode 7.3.1.
Any help much appreciated and apologies up front if this is a dumb question - which I expect it is.
I think you are facing the issue because of the typo in the function.
This is what you are using:
func textField(textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {...}
This is how the function should be:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {...}
just copy and paste this lines in your ViewDidLoad and have a try with this textField
let txtField: UITextField = UITextField(frame: CGRect(x: 0, y: 0, width: 400.00, height: 30.00));
txtField.delegate = self