问题
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