Сбой приложения: исключение - нераспознанный селектор отправлен на экземпляр - PullRequest
0 голосов
/ 16 января 2020

У меня есть UITableviewController со следующей логикой c, чтобы скользить вверх / вниз по всему представлению, когда клавиатура переключается следующим образом:

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
    }
...
}

Переключение клавиатуры затем приводит к сбою приложения со следующим исключением: ChatDetailViewController keyboardWillShow:]: нераспознанный селектор отправлен в экземпляр 0x7f82fc41fdf0

На первый взгляд, сообщение об ошибке кажется ясным, но я все еще не могу понять, что не так с моим селектором. Никаких кодовых предупреждений, никаких опечаток, ...

Что я здесь не так делаю?

Ответы [ 3 ]

2 голосов
/ 16 января 2020

В Swift 4 я ранее использовал вот так

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")
}

В Swift 5 они переименовали способ доступа к уведомлениям клавиатуры на go через 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)
}
0 голосов
/ 16 января 2020

Три вопроса:

  • Создание селектора неверно (используйте #selector)
  • Неправильная подпись действия (отсутствует подчеркивание)
  • Действие должно быть помечено как @objc

И тип в Swift Notification без префикса NS

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
}

...
0 голосов
/ 16 января 2020

Вы забыли добавить @ obj c 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) {}

...