iosswiftuitextfieldbecomefirstresponder

How do I make the keyboard appear and the text field begin editing when the view is tapped


I am trying to make it so that when the user touches the UIView the keyboard appears and the user can type in the textField. I am unable to make the view a first responder how can I make this possible?

Below is the code:

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var searchBar: UITextField!
    var isKeyboardShowing:Bool = true
    var viewTapped:UITapGestureRecognizer = UITapGestureRecognizer()

    override func viewDidLoad() {
        super.viewDidLoad()
        searchBar.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -500).isActive = true
        viewTapped = UITapGestureRecognizer(target: self, action: #selector(viewWasTapped))
        self.view.addGestureRecognizer(viewTapped)


        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: .UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
        searchBar.delegate = self
    }

    override func viewWillAppear(_ animated: Bool) {
        self.searchBar.resignFirstResponder()
        self.view.becomeFirstResponder()
        print("Can the view be the first responder: \(self.view.canBecomeFirstResponder)")
        print("the searchbar is the first responder: \(searchBar.isFirstResponder)")
        print("the view is the first responder: \(self.view.isFirstResponder)")
    }

    @objc func viewWasTapped(){
    print("The view was tapped")
        if isKeyboardShowing{
            view.endEditing(true)
        }
        else{

        }
    }

    @objc func keyboardWillShow(notification: NSNotification) {
        print("keyboardWillShow")
    }

    @objc func keyboardWillHide(notification: NSNotification){
        print("keyboardWillHide")
    }

}

Solution

  • You don't want to make self.view the first responder. You want to make searchBar the first responder.

    And there is no reason to call resignFirstResponder on one view if you are going to call becomeFirstResponder on another view.

    class ViewController: UIViewController, UITextFieldDelegate {
        @IBOutlet weak var searchBar: UITextField!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            searchBar.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -500).isActive = true
            searchBar.delegate = self
    
            let viewTapped = UITapGestureRecognizer(target: self, action: #selector(viewWasTapped))
            self.view.addGestureRecognizer(viewTapped)
    
            NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: .UIKeyboardWillShow, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
        }
    
        override func viewWillAppear(_ animated: Bool) {
            searchBar.becomeFirstResponder()
    
            print("Can the view be the first responder: \(self.view.canBecomeFirstResponder)")
            print("the searchbar is the first responder: \(searchBar.isFirstResponder)")
            print("the view is the first responder: \(self.view.isFirstResponder)")
        }
    
        @objc func viewWasTapped(){
            print("The view was tapped")
            if searchBar.isFirstResponder {
                searchBar.resignFirstResponder()
            } else{
                searchBar.becomeFirstResponder()
            }
        }
    

    Also, searchBar isn't the best name for a UITextField.

    No need for viewTapped to be a property. Make it a local variable.

    No need for the isKeyboardShowing property.