App crashing: Exception - unrecognised selector sent to instance

倾然丶 夕夏残阳落幕 提交于 2020-01-25 07:58:10

问题


I've got a UITableviewController with following logic to slide up / down the entire view once the keyboard toggles like so:

class ChatDetailViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
 // variables...

 override func viewDidLoad() {
        super.viewDidLoad()
        // do stuff...
        NotificationCenter.default.addObserver(self, selector: Selector(("keyboardWillShow:")), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: Selector(("keyboardWillHide:")), name: UIResponder.keyboardWillHideNotification, object: nil)
       // do other stuff...
}
...
func keyboardWillShow(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            self.view.frame.origin.y -= keyboardSize.height
        }
    }

    func keyboardWillHide(notification: NSNotification) {
        self.view.frame.origin.y = 0
    }
...
}

Toggling the keyboard then crashes the App with following exception: ChatDetailViewController keyboardWillShow:]: unrecognized selector sent to instance 0x7f82fc41fdf0

The error message seems clear at first glance but I still can't figure out what's wrong with my selector. No code warnings, no typos,...

What is it I'm doing wrong here?


回答1:


Three issues:

  • The creation of the selector is wrong (use #selector)
  • The signature of the action is wrong (missing underscore)
  • The action must be marked as @objc

And the type in Swift is Notification without NS prefix

override func viewDidLoad() {
    super.viewDidLoad()
    // do stuff...
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
    // do other stuff...
}

    ...

@objc func keyboardWillShow(_ notification: Notification) {
    if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        self.view.frame.origin.y -= keyboardSize.height
    }
}

@objc func keyboardWillHide(_ notification: Notification) {
    self.view.frame.origin.y = 0
}

...



回答2:


In Swift 4 i have previously used in like this

override func viewDidLoad() {
    super.viewDidLoad()   
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

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

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

In Swift 5 they renamed the way to access the keyboard notifications to go through UIResponder:

override func viewDidLoad() {
    super.viewDidLoad()   
    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)
}



回答3:


u forgot to add @objc part

NotificationCenter.default.addObserver(self,
                                               selector: #selector(keyboardWillShow),
                                               name: UIResponder.keyboardWillShowNotification,
                                               object: nil)
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(keyboardWillHide),
                                               name: UIResponder.keyboardWillHideNotification,
                                               object: nil)
@objc func keyboardWillShow(_ sender: Notification) {}
@objc func keyboardWillHide(_ sender: Notification) {}



来源:https://stackoverflow.com/questions/59773010/app-crashing-exception-unrecognised-selector-sent-to-instance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!