Search code examples
swiftkeyboardresignfirstresponder

resignFirstResponder is not working as expected.the key board pop's down for every key press rather than for return only


i have 3 UITextField. when i set the resignFirstResponder for the text field, for every key press the key board goes down and key board pops up when we enter. which means for each letter pressed the key board disappears

I tried creating an outlet for the text field as below but the print statement is executed but the key board is not getting disappeared when focus lost or moved to the next text field

         @IBAction func done(_ sender: UITextField) {
                print("Text field done$$$$$$$$$$$$$$$")
                sender.endEditing(true)
                sender.resignFirstResponder()
        //        print("After Resign")
            } 

tried the below one also:

self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:)))) 
     override func viewDidLayoutSubviews() {

            super.viewDidLayoutSubviews()

            //Textfield
            let textfield = UITextField()
            textfield.setShadowTextField(username, "user-name")
            textfield.setShadowTextField(useremail, "email")
            textfield.setShadowTextField(userPhone, "phone")

            //Hide Keyboard
           textName.resignFirstResponder()
            textEmail.resignFirstResponder()
            userPhone.resignFirstResponder()
            //
            name = textName.text ?? ""
            emailphone = textEmail.text ?? ""

            //Button

            if isFirstTimeSubView == true {
                button?.setSemiButtonLeft(btnFemaleSelector, shadowViewFemale)
                button?.setGradientButton(btnFemaleSelector, startColor: "0d5e90", endColor: "8ec67d")

                button?.setSemiButtonRight(btnMaleSelector, shadowViewMale)
                button?.setGradientButton(btnMaleSelector, startColor: "FFFFFF", endColor: "FFFFFF")
                isFirstTimeSubView = false
            }


            button?.setRoundButton(btnSubmit, shadowView)
            button?.setGradientButton(btnSubmit, startColor: "0d5e90", endColor: "8ec67d")

            //textNam.sendAction("resignFirstResponder", to:nil, from:nil, forEvent:nil)
    //        self.userText.delegate = selftextName.resignFirstResponder()
        }
extension UITextField {
    func setShadowTextField(_ textfield: UITextField?, _ imagename: String?) {
        // set color & border
        textfield?.borderStyle = .none
        textfield?.backgroundColor = UIColor.white
        // set corner
        textfield?.layer.cornerRadius = (textfield?.frame.size.height ?? 0.0) / 2
        //set shadow
        textfield?.layer.shadowOpacity = 0.4
        textfield?.layer.shadowRadius = 15
        textfield?.layer.shadowOffset = CGSize(width: 5, height: 10)
        textfield?.layer.shadowColor = UIColor.gray.cgColor
        // set icon & Placeholder position
        let UIViewController = UIView(frame: CGRect(x: 0, y: 0, width: 60, height: textfield?.frame.size.height ?? 0.0))
        let icon = UIImageView(image: UIImage(named: imagename ?? ""))

        icon.frame = CGRect(x: 0, y: 0, width: UIViewController.frame.size.width / 4, height: UIViewController.frame.size.height / 4)
        icon.center = UIViewController.center

        UIViewController.addSubview(icon)
        textfield?.leftView = UIViewController
        textfield?.leftViewMode = .always
    }
}

Solution

  • The question is a little unclear but if you want the keyboard to go down when you've pressed the done button, you should implement the UITextFieldDelegate on your view controller and during the textFieldShouldReturn(_:) method call resignFirstResponder from there:

    class myVC: UIViewController, UITextFieldDelegate{    
        func textFieldShouldReturn(_ textField: UITextField) -> Bool{
            return true
        }
    }
    

    and don't forget to set the delegate in the viewDidLoad for your VC:

    override func viewDidLoad() {
        super.viewDidLoad()
        /// Text field delegate handling
        textFieldFirstName.delegate = self
    }
    

    https://developer.apple.com/documentation/uikit/uitextfielddelegate/1619603-textfieldshouldreturn?language=objc

    By calling resignFirstResponder in viewDidLayoutSubviews, you are resigning the responder every time the viewDidLayoutSubviews is called, i.e. When the bounds change for a view controller's view, the view adjusts the positions of its subviews and then the system calls this method. So I presume the keyboard will be changing the bounds, causing viewDidLayoutSubviews to fire after each keypress and creating the behaviour you are seeing