ios - 为什么无法识别的选择器发送到实例?

标签 ios swift iphone xcode swift4.2

我正在尝试制作一个方便的将键盘绑定(bind)到 uiview 函数。我无法解决这个错误

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Twitter.LoginVC handleKeyboard:]: unrecognized selector sent to instance 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)
}
}

在 vc 的 viewDidLoad() 中:

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

最佳答案

您正在尝试将选择器发送到 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)
}

然后当你使用它时,你会这样做:

NotificationService.instance.addKeyboardObservers(self, handleKeyboardSelector: #selector(self.handleKeyboard(_:)))

正如您所看到的,您现在正在指示触发 self 上的选择器,因为实际上 self 具有该方法。 作为一般规则:选择器被发送到实例,因此该实例必须具有所选方法。


如果您确实想将选择器发送到 viewController 实例,您可以创建一个扩展,将该方法添加到每个 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

编辑 尝试在 View Controller 中保留键盘服务:

let keyboardService = KeyboardService()

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

关于ios - 为什么无法识别的选择器发送到实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55400699/

相关文章:

ios - 执行选择器 :withObject:afterDelay not calling selector

swift - 如何将我的标签返回到它在 Swift 中的初始位置 (UIGestureRecognizer)

ios - 将 UIScrollView 连接到 UIView 类

iphone - 是否可以像读取 RFID 标签一样读取 iPhone 的 NFC 芯片?

ios - 选择器中的 Swift 传递参数

ios - Swift 中的通用类继承

iOS - NSJSON 序列化 : Unable to convert data to string around character

带有 SpriteKit 的 iOS 通用设备应用程序,如何为所有 View 缩放节点?

iphone - 动画绘制线条

iphone - 是什么导致帧率下降?