Search code examples
iosswiftuibuttonuitextfielddelegate

Disable UIButton w/ textFieldDidBeginEditing requires clicking off of UITextField to take effect


With the UITextFieldDelegate, I'm disabling my UIButton "btnSignup" based on whether 3 UITextFields contain information or not. Currently, it works appropriately minus the fact that for the UIButton to reactive (run through the if statement again), I have to click off of the UITextField. The same is true for when I've typed something and I go back to delete it. The UIButton remains active until I click off of the UITextField (if I click submit without clicking elsewhere, I am able to submit, which shouldn't be the case.)

class MainVC: UIViewController, UITextFieldDelegate {

    @IBOutlet var receiveName: UITextField!
    @IBOutlet var receiveEmail: UITextField!
    @IBOutlet var receivePhone: UITextField!
    @IBOutlet var btnSignup: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.btnSignup.enabled = false
        self.btnSignup.alpha = 0.3

        self.receiveName.delegate = self
        self.receiveEmail.delegate = self
        self.receivePhone.delegate = self

    func textFieldDidBeginEditing(textField: UITextField) {

        if countElements(receiveName.text) > 0 && countElements(receiveEmail.text) > 0 && countElements(receivePhone.text) > 0 {
            self.btnSignup.enabled = true
            self.btnSignup.alpha = 1
        } else {
            self.btnSignup.enabled = false
            self.btnSignup.alpha = 0.3
        }
    }
}

I am looking for a solution that gives a more realtime effect. The function should be listening and responding if at any time the UITextField is being edited.


Solution

  • Using something close to your code I could do this as below. I added 3 class level. variables to record if the text fields had something entered. I added tags to the text fields. I changed the UITextFieldDelegate class func and tested that all three fields have text. The second you enter a field in the third field, the button lights up!

    import UIKit
    
    class ViewController: UIViewController, UITextFieldDelegate {
        var receiveNameBool = false
        var receiveEmailBool = false
        var receivePhoneBool = false
    
        @IBOutlet var receiveName: UITextField!
        @IBOutlet var receiveEmail: UITextField!
        @IBOutlet var receivePhone: UITextField!
        @IBOutlet var btnSignup: UIButton!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.btnSignup.enabled = false
            self.btnSignup.alpha = 0.3
    
            self.receiveName.delegate = self
            self.receiveEmail.delegate = self
            self.receivePhone.delegate = self
    
            }
    
        func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool {
    
            if textField.tag == 1 {
                receiveNameBool = true
            } else if textField.tag == 2 {
                receiveEmailBool = true
            } else if textField.tag == 3 {
                receivePhoneBool = true
            }
    
            if receiveNameBool && receiveEmailBool && receivePhoneBool {
                self.btnSignup.enabled = true
                self.btnSignup.alpha = 1
            } else {
                self.btnSignup.enabled = false
                self.btnSignup.alpha = 0.3
            }
            return true
        }
    }
    

    Okay, in this second version, I used the textFieldDidBeginEditing func you used. Un this case the second you click inside the third field the button is enabled. In both examples you need to still write code to deal with the case if the user deletes the data they entered. But the first example above gets you what you wanted.

    import UIKit

    class ViewController: UIViewController, UITextFieldDelegate {
        var receiveNameBool = false
        var receiveEmailBool = false
        var receivePhoneBool = false
    
        @IBOutlet var receiveName: UITextField!
        @IBOutlet var receiveEmail: UITextField!
        @IBOutlet var receivePhone: UITextField!
        @IBOutlet var btnSignup: UIButton!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.btnSignup.enabled = false
            self.btnSignup.alpha = 0.3
    
            self.receiveName.delegate = self
            self.receiveEmail.delegate = self
            self.receivePhone.delegate = self
    
            }
    
        func textFieldDidBeginEditing(textField: UITextField) {
    
            if textField.tag == 1 {
                receiveNameBool = true
            } else if textField.tag == 2 {
                receiveEmailBool = true
            } else if textField.tag == 3 {
                receivePhoneBool = true
            }
    
            if receiveNameBool && receiveEmailBool && receivePhoneBool {
                self.btnSignup.enabled = true
                self.btnSignup.alpha = 1
            } else {
                self.btnSignup.enabled = false
                self.btnSignup.alpha = 0.3
            }
        }
    }