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...
Related
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.
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
}
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
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
i created a username textfield and i want my textfield do not accept the numbers in swift 5
i tried this bud didnt work
func OnlyCharacter(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let allowedcharacters = CharacterSet.decimalDigits
let characterset = CharacterSet(charactersIn: string)
return allowedcharacters.isSuperset(of: characterset)
}
You have to change only CharacterSet.decimalDigits to NSCharacterSet.letterCharacterSet()
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if string.rangeOfCharacter(from: .letters) != nil {
return true
} else {
return false
}
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let non_digits = NSCharacterSet.letters.inverted
let range = string.rangeOfCharacter(from: non_digits)
if range != nil { // found an invalid
return false
}
return true
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let characterSet = CharacterSet.letters //accept letters only here
if string.rangeOfCharacter(from:characterSet.inverted) != nil {
return false
}
return true
}