0

I have a textField that I disable capital letters by setting .autocapitalizationType = .none and in shouldChangeCharactersIn range I replace any capital letters with lowercased letters by using this answer.

Forcing only lowercase letters works fine but the target method I added to .editingChanged stopped working.

Why did .editingChanged stop working?

let emailTextField: UITextField = {
    let textField = UITextField()
    return textField
}()

let userNameTextField: UITextField = {
    let textField = UITextField()
    textField.autocapitalizationType = .none
    textField.addTarget(self, action: #selector(printSomething), for: .editingChanged)
    return textField
}()

@objc func printSomething() {
    // as I type inside the usernameTextField this no longer prints
    print("something")
}

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    // only change characters for username textfield
    if textField == userNameTextField {

        userNameTextField.text = (textField.text! as NSString).replacingCharacters(in: range, with: string.lowercased())
        return false
    }
    return true
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
Lance Samaria
  • 17,576
  • 18
  • 108
  • 256

2 Answers2

1

Change to return true

   if textField == userNameTextField {

        userNameTextField.text = (textField.text! as NSString).replacingCharacters(in: range, with: string.lowercased())
        return true
    }
user1376400
  • 614
  • 1
  • 4
  • 8
0

The problem is your userNameTextField declaration. When you initialise it there is no self. You need to change its declaration to lazy:

lazy var userNameTextField: UITextField = {
    let textField = UITextField()
    textField.autocapitalizationType = .none
    textField.addTarget(self, action: #selector(editingChanged), for: .editingChanged)
    return textField
}()

I would also remove the shouldChangeCharacters in range and do all your character manipulation inside editingChanged method:

@objc func editingChanged(_ textField: UITextField) {
    print(textField.text!)
    textField.text = textField.text!.lowercased()
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • Hey thanks for the help but it didn’t work. Everything worked fine with the constant declaration until I added the shouldChangeCharatets method. – Lance Samaria Feb 28 '19 at 13:28
  • I added the target to viewDidLoad after the delegate and it still doesn’t work. – Lance Samaria Feb 28 '19 at 13:32
  • you mean `userNameTextField.addTarget(self, action: #selector(printSomething), for: .editingChanged)` declaring it normally? Try `the lazy var` approach as it is. It has to work. – Leo Dabus Feb 28 '19 at 13:33
  • hey thanks this worked. You can remove the first part of your answer about the closure (for clarity) because your .editingChanged method fixed it. Btw I think you should add your answer to this question https://stackoverflow.com/questions/31989028/typing-always-force-lowercase-or-uppercase-ios-swift/31989029#31989029 because it's a really easy fix and it prevents the unforeseen problem that I had. Thanks for the help!!! – Lance Samaria Feb 28 '19 at 13:56
  • @LanceSamaria. I rolled back your edits so people will understand why lazy was needed. – Leo Dabus Feb 28 '19 at 13:58
  • I added a link to your answer underneath the other lowercase question. – Lance Samaria Feb 28 '19 at 14:04
  • Sorry I didn't see any link – Leo Dabus Feb 28 '19 at 14:07
  • I placed it under the question itself instead of the accepted answer. I just moved it: https://stackoverflow.com/questions/31989028/typing-always-force-lowercase-or-uppercase-ios-swift/31989029#31989029 – Lance Samaria Feb 28 '19 at 14:15
  • @LanceSamaria I see. You can just paste a link to this answer in comments there. – Leo Dabus Feb 28 '19 at 14:17