junbok
junbok

Reputation: 11

keyboard willshow and didshow called twice in the first time

I want to show myView on the keyboard using keyboardWillShow, but keyboardWillShow is called twice so I can't modify myView's BottomConstraint

I think it's because of the UItextfield inputaccessoryView. I need keyboardWillShow to get called only once, What should I do?

This is my Code

import UIKit
import SnapKit

class ViewController: UIViewController {
    
    let tableView = UITableView()
    let textField = UITextField()
    let myView = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.backgroundColor = . green
        myView.backgroundColor = .yellow
        textField.backgroundColor = .red
        myView.addSubview(textField)
        self.view.addSubview(tableView)
        self.view.addSubview(myView)
        
        textField.snp.makeConstraints {
            $0.top.leading.equalTo(10)
            $0.bottom.trailing.equalTo(-10)
        }
                
        myView.snp.makeConstraints {
            $0.leading.equalTo(10)
            $0.bottom.trailing.equalTo(-10)
            $0.height.equalTo(50)
        }
        
        tableView.snp.makeConstraints {
            $0.top.leading.equalTo(10)
            $0.bottom.trailing.equalTo(-10)
        }
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
        view.addGestureRecognizer(tapGesture)
       
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification , object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
      
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        NotificationCenter.default.removeObserver(self)
        
    }
    
    @objc func dismissKeyboard(sender: UITapGestureRecognizer) {
        textField.resignFirstResponder()
    }

    @objc func keyboardWillShow(_ noti: NSNotification){
        print("willshow")
    }

    @objc func keyboardWillHide(_ noti: NSNotification){
        print("willhide")
    }

    
}

Upvotes: 1

Views: 378

Answers (1)

Omer Tekbiyik
Omer Tekbiyik

Reputation: 4764

You cannot guarantee that keyboardwillshow or keyboardwillhide will work once. For example, when the keyboard is open and the application is turned into the background and reopened, this notification works again.

Also , Apple recommends using notifications in viewWillAppear and remove when the work is done , like that :

  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    navigationController?.interactivePopGestureRecognizer!.isEnabled = true

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name:UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name:UIResponder.keyboardWillHideNotification, object: nil)
    
    self.navigationController?.setNavigationBarHidden(true, animated: true)
}
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    
    NotificationCenter.default.removeObserver(self)

}

Do not forget that these are notifications, if there is this notification (keyboard will show or hide) on another page that is live, it will work in the functions on that page. this can cause undesired results

That's why we need to remove notifications when page goes off screen

Upvotes: 1

Related Questions