How do I check when a UITextField changes?

IosSwiftUitextfield

Ios Problem Overview


I am trying to check when a text field changes, equivalent too the function used for textView - textViewDidChange so far I have done this:

  func textFieldDidBeginEditing(textField: UITextField) {
        if self.status.text == "" && self.username.text == "" {
            self.topRightButton.enabled = false
        } else {   
            self.topRightButton.enabled = true
        }
    }

Which kind of works, but the topRightButton is enabled as soon as the text field is pressed on, I want it to be enabled only when text is actually typed in?

Ios Solutions


Solution 1 - Ios

SWIFT

Swift 4.2

textfield.addTarget(self, action: #selector(ViewController.textFieldDidChange(_:)), for: .editingChanged)

and

@objc func textFieldDidChange(_ textField: UITextField) {
    
}

SWIFT 3 & swift 4.1

textField.addTarget(self, action: #selector(ViewController.textFieldDidChange(_:)), for: .editingChanged)

and

func textFieldDidChange(_ textField: UITextField) {
    
}

SWIFT 2.2

textField.addTarget(self, action: #selector(ViewController.textFieldDidChange(_:)), forControlEvents: UIControlEvents.EditingChanged)

and

func textFieldDidChange(textField: UITextField) {
    //your code
}

OBJECTIVE-C

[textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

and textFieldDidChange method is

-(void)textFieldDidChange :(UITextField *) textField{
    //your code
}

Solution 2 - Ios

You can make this connection in interface builder.

  1. In your storyboard, click the assistant editor at the top of the screen (two circles in the middle). Assistant editor selected

  2. Ctrl + Click on the textfield in interface builder.

  3. Drag from EditingChanged to inside your view controller class in the assistant view. Making connection

  4. Name your function ("textDidChange" for example) and click connect. Naming function

Solution 3 - Ios

Swift 5.0

textField.addTarget(self, action: #selector(ViewController.textFieldDidChange(_:)),
                          for: .editingChanged)

and handle method:

@objc func textFieldDidChange(_ textField: UITextField) {
    
}

Swift 4.0

textField.addTarget(self, action: #selector(ViewController.textFieldDidChange(_:)),
                          for: UIControlEvents.editingChanged)

and handle method:

@objc func textFieldDidChange(_ textField: UITextField) {
    
}

Swift 3.0

textField.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged)

and handle method:

func textFieldDidChange(textField: UITextField) { 

}

Solution 4 - Ios

The way I've handled it so far: in UITextFieldDelegate

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
    // text hasn't changed yet, you have to compute the text AFTER the edit yourself
    let updatedString = (textField.text as NSString?)?.stringByReplacingCharactersInRange(range, withString: string)
    
    // do whatever you need with this updated string (your code)
    

    // always return true so that changes propagate
    return true
}

Swift4 version

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let updatedString = (textField.text as NSString?)?.replacingCharacters(in: range, with: string)
    return true
}

Solution 5 - Ios

Swift 3

 textField.addTarget(self, action: #selector(ViewController.textFieldDidChange(sender:)), for: UIControlEvents.editingChanged)

Solution 6 - Ios

textField(_:shouldChangeCharactersIn:replacementString:) worked for me in Xcode 8, Swift 3 if you want to check every single keypress.

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
    // Whatever code you want to run here.
    // Keep in mind that the textfield hasn't yet been updated,
    // so use 'string' instead of 'textField.text' if you want to
    // access the string the textfield will have after a user presses a key

    var statusText = self.status.text
    var usernameText = self.username.text

    switch textField{
    case self.status:
        statusText = string
    case self.username:
        usernameText = string
    default:
        break
    }

    if statusText == "" && usernameText == "" {
        self.topRightButton.enabled = false
    } else {   
        self.topRightButton.enabled = true
    }

    //Return false if you don't want the textfield to be updated
    return true
}

Solution 7 - Ios

Swift 3.0.1+ (Some of the other swift 3.0 answers are not up to date)

textField.addTarget(self, action: #selector(ViewController.textFieldDidChange(_:)),
                          for: UIControlEvents.editingChanged)

func textFieldDidChange(_ textField: UITextField) {
        
}

Solution 8 - Ios

You can use this delegate method from UITextFieldDelegate. It fires with every character change.

(Objective C) textField:shouldChangeCharactersInRange:replacementString:
(Swift) textField(_:shouldChangeCharactersInRange:replacementString:)

However THIS ONLY FIRES BEFORE a change is made (indeed, a change is only made if you do return true from here).

Solution 9 - Ios

Swift 4

Conform to UITextFieldDelegate.

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    // figure out what the new string will be after the pending edit
    let updatedString = (textField.text as NSString?)?.replacingCharacters(in: range, with: string)

    // Do whatever you want here


    // Return true so that the change happens
    return true
}

Solution 10 - Ios

There's now a UITextField delegate method available on iOS13+

optional func textFieldDidChangeSelection(_ textField: UITextField)

Solution 11 - Ios

Maybe use RxSwift ?

need

pod 'RxSwift',    '~> 3.0'
pod 'RxCocoa',    '~> 3.0'

add imports obviously

import RxSwift
import RxCocoa

So u have a textfield : UITextField

let observable: Observable<String?> = textField.rx.text.asObservable()
observable.subscribe(
            onNext: {(string: String?) in
                print(string!)
        })

U have other 3 methods..

  1. onError
  2. onCompleted
  3. onDisposed
  4. onNext

Solution 12 - Ios

Swift 4

textField.addTarget(self, action: #selector(textIsChanging), for: UIControlEvents.editingChanged)

@objc func textIsChanging(_ textField:UITextField) {

 print ("TextField is changing")

}

If you want to make a change once the user has typed in completely (It will be called once user dismiss keyboard or press enter).

textField.addTarget(self, action: #selector(textDidChange), for: UIControlEvents.editingDidEnd)

 @objc func textDidChange(_ textField:UITextField) {

       print ("TextField did changed") 
 }

Solution 13 - Ios

txf_Subject.addTarget(self, action:#selector(didChangeFirstText), for: .editingChanged)

@objc func didChangeText(textField:UITextField) {
    let str = textField.text
    if(str?.contains(" "))!{
        let newstr = str?.replacingOccurrences(of: " ", with: "")
        textField.text = newstr
    }
}

@objc func didChangeFirstText(textField:UITextField) {
    if(textField.text == " "){
        textField.text = ""
    }
}

Solution 14 - Ios

You should follow this steps:

  1. Make a Outlet reference to the textfield
  2. AssignUITextFieldDelegate to the controller class
  3. Configure yourTextField.delegate
  4. Implement whatever function you need

Sample code:

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var yourTextFiled : UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        yourTextFiled.delegate = self
    }


    func textFieldDidEndEditing(_ textField: UITextField) {
        // your code
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        // your code
    }

    .
    .
    .
}

Solution 15 - Ios

Swift 4.2

write this in viewDidLoad

// to detect if TextField changed
TextField.addTarget(self, action: #selector(textFieldDidChange(_:)),
                                   for: UIControl.Event.editingChanged)

write this outside viewDidLoad

@objc func textFieldDidChange(_ textField: UITextField) {
    // do something
}

You could change the event by UIControl.Event.editingDidBegin or what ever you want to detect.

Solution 16 - Ios

This is how you can add a textField text change listener using Swift 3:

Declare your class as UITextFieldDelegate

override func viewDidLoad() {
    super.viewDidLoad()

    textField.delegate = self

    textField.addTarget(self, action: #selector(UITextFieldDelegate.textFieldShouldEndEditing(_:)), for: UIControlEvents.editingChanged)
}

Then just traditionally add a textFieldShouldEndEditing function:

func textFieldShouldEndEditing(_ textField: UITextField) -> Bool { // do stuff
        return true 
}

Solution 17 - Ios

Just in case you are interested in a SwiftUI solution, this it's working for me:

 TextField("write your answer here...",
            text: Binding(
                     get: {
                        return self.query
                       },
                     set: { (newValue) in
                        self.fetch(query: newValue) // any action you need
                                return self.query = newValue
                      }
            )
  )

I have to say it's not my idea, I read it in this blog: SwiftUI binding: A very simple trick

Solution 18 - Ios

In case it is not possible to bind the addTarget to your UITextField, I advise you to bind one of them as suggested above, and insert the code for execution at the end of the shouldChangeCharactersIn method.

nameTextField.addTarget(self, action: #selector(RegistrationViewController.textFieldDidChange(_:)), for: .editingChanged)

@objc func textFieldDidChange(_ textField: UITextField) {
    if phoneNumberTextField.text!.count == 17 && nameTextField.text!.count > 0 {
        continueButtonOutlet.backgroundColor = UIColor(.green)
    } else {
        continueButtonOutlet.backgroundColor = .systemGray
    }
}

And in call in shouldChangeCharactersIn func.

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
    guard let text = textField.text else {
        return true
    }
    let lastText = (text as NSString).replacingCharacters(in: range, with: string) as String
    
    if phoneNumberTextField == textField {
        textField.text = lastText.format("+7(NNN)-NNN-NN-NN", oldString: text)
        textFieldDidChange(phoneNumberTextField)
        return false
    }
    return true
}

Solution 19 - Ios

swift 4

In viewDidLoad():

    //ADD BUTTON TO DISMISS KEYBOARD
    
    // Init a keyboard toolbar 
    let toolbar = UIView(frame: CGRect(x: 0, y: view.frame.size.height+44, width: view.frame.size.width, height: 44))
    toolbar.backgroundColor = UIColor.clear
    
    // Add done button
    let doneButt = UIButton(frame: CGRect(x: toolbar.frame.size.width - 60, y: 0, width: 44, height: 44))
    doneButt.setTitle("Done", for: .normal)
    doneButt.setTitleColor(MAIN_COLOR, for: .normal)
    doneButt.titleLabel?.font = UIFont(name: "Titillium-Semibold", size: 13)
    doneButt.addTarget(self, action: #selector(dismissKeyboard), for: .touchUpInside)
    toolbar.addSubview(doneButt)
    
    USDTextField.inputAccessoryView = toolbar

Add this function:

    @objc func dismissKeyboard() {
      //Causes the view (or one of its embedded text fields) to resign the first responder status.
      view.endEditing(true)
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser4184036View Question on Stackoverflow
Solution 1 - IosFawad MasudView Answer on Stackoverflow
Solution 2 - IosrmooneyView Answer on Stackoverflow
Solution 3 - IosRobertView Answer on Stackoverflow
Solution 4 - IosVinzzzView Answer on Stackoverflow
Solution 5 - IosAlessandro MattiuzziView Answer on Stackoverflow
Solution 6 - Iosradthemad4View Answer on Stackoverflow
Solution 7 - IosAviranView Answer on Stackoverflow
Solution 8 - IosAbubakr DarView Answer on Stackoverflow
Solution 9 - IosdrewsterView Answer on Stackoverflow
Solution 10 - IosJP AquinoView Answer on Stackoverflow
Solution 11 - IosmarlonpyaView Answer on Stackoverflow
Solution 12 - IosAnamikaView Answer on Stackoverflow
Solution 13 - IosYogesh TandelView Answer on Stackoverflow
Solution 14 - IosM.HazaraView Answer on Stackoverflow
Solution 15 - IosGerges EidView Answer on Stackoverflow
Solution 16 - IosCodetardView Answer on Stackoverflow
Solution 17 - IosabanetView Answer on Stackoverflow
Solution 18 - IosСтепан ВарткинаянView Answer on Stackoverflow
Solution 19 - IosNilView Answer on Stackoverflow