Disable back button while keyboard is in use?

I want to disable my back button while the user has the keyboard engaged.


Here's what I have so far:


The "backButton.isEnabled = false" disables the back button perfectly in "viewDidLoad":

class DetailViewController: UIViewController, UITextViewDelegate {

    var backButton = UIBarButtonItem()

      override func viewDidLoad() {
          super.viewDidLoad()

        backButton.title = "Save"
        backButton.isEnabled = false
        self.navigationController?.navigationBar.topItem?.backBarButtonItem = backButton



The below code works to trigger "keyboard is here" and "keyboard is gone" when the keyboard is called/dismissed:

    override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
{

    @objc func keyboardWillShow(notification: Notification) {
        print("keyboard is here")
        
    }

    @objc func keyboardWillHide(notification: Notification) {
        print("keyboard is gone")
    }


However, when I try to drop the "backButton.isEnabled = false" in the "@objc func keyboardWillShow" function, nothing happens.

    @objc func keyboardWillShow(notification: Notification) {
        print("keyboard is here")  
        backButton.isEnabled = false
    }


Not sure why the "backButton.isEnabled = false" works in the viewDidLoad but not keyboardWillShow... Any idea how to fix this?

Answered by Claude31 in 404250022

Sorry, of course need self.


backButton is a navigationItem ?

If so, try to replace by:


self.navigationItem.setHidesBackButton(true, animated:true)

Put it in the main thread:


    @objc func keyboardWillShow(notification: Notification) {
        print("keyboard is here")  
        DispatchQueue.main.async { () -> Void in
            backButton.isEnabled = false
      }
    }

Thanks for the suggestion Claude. I tried the below, did not resolve the issue (error made me include "self" to start the "isEnabled" line):

    @objc func keyboardWillShow(notification: Notification) {
        print("keyboard is here")
          DispatchQueue.main.async { () -> Void in
            self.backButton.isEnabled = false
        }
    }


I click the keyboards, "keyboard is here" prints to the console, but nothing happens to the back button. I'm using both default (qwerty) and decimal pads on keyboards.


Without the "self" in there, the error is: Reference to property 'backButton' in closure requires explicit 'self.' to make capture semantics explicit

Accepted Answer

Sorry, of course need self.


backButton is a navigationItem ?

If so, try to replace by:


self.navigationItem.setHidesBackButton(true, animated:true)

Once again Claude, you're awesome. That worked. Thanks a ton.

Disable back button while keyboard is in use?
 
 
Q