Почему нераспознанный селектор отправлен на экземпляр? - PullRequest
0 голосов
/ 28 марта 2019

Я пытаюсь сделать удобную привязку клавиатуры к функции uiview.Я не могу найти эту ошибку

*** Завершение работы приложения из-за необработанного исключения 'NSInvalidArgumentException', причина: '- [Twitter.LoginVC handleKeyboard:]: нераспознанный селектор отправлен в экземпляр 0x7ffbf142e970'

class KeyboardService {

var constraint: NSLayoutConstraint!
var vc: UIViewController!

func bind(bottomConstraint: NSLayoutConstraint, vc: UIViewController) {
    constraint = bottomConstraint
    self.vc = vc
    NotificationService.instance.addKeyboardObservers(onVC: vc, handleKeyboardSelector: #selector(self.handleKeyboard(_:))) // **CRASHES HERE**
}

@objc func handleKeyboard(_ notification: NSNotification) {
    NotificationService.instance.handleKeyboard(notification: notification, bottomConstraint: constraint, vc: vc)
} 
}

Вот мое уведомлениеСервис:

class NotificationService {
static let instance  = NotificationService()

func addKeyboardObservers(onVC vc: UIViewController, handleKeyboardSelector: Selector) {
    NotificationCenter.default.addObserver(vc, selector: handleKeyboardSelector, name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(vc, selector: handleKeyboardSelector, name: UIResponder.keyboardWillHideNotification, object: nil)
}
}

РЕДАКТИРОВАТЬ:

class KeyboardService {

var constraint: NSLayoutConstraint!
var vc: UIViewController!

func bind(bottomConstraint: NSLayoutConstraint, vc: UIViewController) {
    constraint = bottomConstraint
    self.vc = vc
    NotificationService.instance.addKeyboardObservers(self, handleKeyboardSelector: #selector(self.handleKeyboard(_:)))
}

@objc func handleKeyboard(_ notification: NSNotification) {
    NotificationService.instance.handleKeyboard(notification: notification, bottomConstraint: constraint, vc: vc)
}

}

РЕДАКТИРОВАТЬ 2:

class KeyboardService {

var constraint: NSLayoutConstraint!
var vc: UIViewController!

func bind(bottomConstraint: NSLayoutConstraint, vc: UIViewController) {
    constraint = bottomConstraint
    self.vc = vc
    NotificationService.instance.addKeyboardObservers(self, handleKeyboardSelector: #selector(handleKeyboard(_:)))
}

@objc func handleKeyboard(_ notification: NSNotification) {
    NotificationService.instance.handleKeyboard(notification: notification, bottomConstraint: constraint, vc: vc)
}
}

В viewDidLoad () виртуального канала:

KeyboardService().bind(bottomConstraint: loginBtnBackViewBottomConstraint, vc: self)

1 Ответ

0 голосов
/ 28 марта 2019

Вы пытаетесь отправить селектор на vc;но это UIViewController, который на самом деле не имеет метода с именем handleKeyboard(_:).Вы должны изменить этот метод регистрации на:

func addKeyboardObservers(_ observer: Any, handleKeyboardSelector: Selector) {
    NotificationCenter.default.addObserver(observer, selector: handleKeyboardSelector, name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(observer, selector: handleKeyboardSelector, name: UIResponder.keyboardWillHideNotification, object: nil)
}

И затем, когда вы используете его, вы должны сделать:селектор на self, потому что на самом деле self имеет этот метод.Как правило: селектор отправляется экземпляру, поэтому именно этот экземпляр должен иметь выбранный метод.


Если вы действительно хотите отправить селектор экземпляру viewController, вы можете создать extension, который добавляет метод к каждому UIViewController

extension UIViewController {

    @objc func handleKeyboard(_ notification: NSNotification) {
        // do your stuff here
    }
}

Затем,при регистрации выполните:

NotificationService.instance.addKeyboardObservers(onVC: vc, handleKeyboardSelector: #selector(vc.handleKeyboard(_:))) // notice the vc.handleKeyboard instead of self.handleKeyboard

EDIT Попробуйте сохранить службу клавиатуры в контроллере вида:

let keyboardService = KeyboardService()

override func viewDidLoad() {
    super.viewDidLoad()
    keyboardService.bind(bottomConstraint: loginBtnBackViewBottomConstraint, vc: self)
}
...