【发布时间】:2017-05-16 19:40:49
【问题描述】:
我正在尝试制定一个 ViewController 可以实现的协议,以调整其视图以适应键盘显示/隐藏。
protocol KeyboardAdaptable {
func keyboardWillShow(notification: NSNotification)
func keyboardWillHide(notification: NSNotification)
func addKeyboardNotificationObservers()
}
extension KeyboardAdaptable where Self: UIViewController, Self: NSObject {
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
if self.view.frame.origin.y == 0{
self.view.frame.origin.y -= keyboardSize.height
}
}
}
func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
if self.view.frame.origin.y != 0{
self.view.frame.origin.y += keyboardSize.height
}
}
}
func addKeyboardNotificationObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
}
错误:“#selector 的参数引用了未暴露给 Objective-C 的实例方法 'keyboardWillShow'。”
我知道选择器是 Objective-C 的一个特性,并且引用的函数必须是兼容的。我试图通过用@objc 注释标记协议本身以及方法来解决这个问题,但是编译器坚持我也用@objc 标记协议扩展中的默认实现。当我这样做时,它向我大喊要删除 @objc 注释,因为 “@objc 只能用于类的成员、@objc 协议和类的具体扩展”(即不在协议中扩展?)
有人知道实现这一目标的方法吗?我知道乍一看似乎没有办法绕过它,但我也知道 UIViewController 是 NSObject 的子对象,通常 UIViewControllers 上的实例方法被允许成为选择器的目标。我认为通过对我的协议扩展施加约束,要求它是 UIViewController 的子类,我可以使用选择器来定位其中包含的默认实现。
想法?
【问题讨论】:
标签: ios objective-c swift uiviewcontroller selector