【发布时间】:2017-01-11 04:18:25
【问题描述】:
我有一个应用程序在几个不同的控制器中使用 UIKeyboardWillShow & Hide 通知。我决定尝试将使用键盘移动视图所需的逻辑整合到基于协议的扩展中。
这是我的协议
public protocol KeyboardType : class {
func keyboardWillShow(_ sender: Notification)
func keyboardWillHide(_ sender: Notification)
}
接下来,我为我的新协议添加了一个扩展,因此我需要做的就是实现我的“KeyboardType”协议,然后我将获得使用键盘移动视图所需的功能:
这是我的扩展程序
public extension KeyboardType where Self: UIViewController {
func addObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(Self.keyboardWillShow(_:)), name:NSNotification.Name.UIKeyboardWillShow, object: self.view.window)
NotificationCenter.default.addObserver(self, selector: #selector(Self.keyboardWillHide(_:)), name:NSNotification.Name.UIKeyboardWillHide, object: self.view.window)
}
func removeObservers() {
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: self.view.window)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: self.view.window)
}
func keyboardWillHide(_ sender: Notification) {
let userInfo: [AnyHashable : Any] = (sender as NSNotification).userInfo!
let keyboardSize: CGSize = (userInfo[UIKeyboardFrameBeginUserInfoKey]! as AnyObject).cgRectValue.size
self.view.frame.origin.y += keyboardSize.height
}
func keyboardWillShow(_ sender: Notification) {
let userInfo: [AnyHashable : Any] = sender.userInfo!
let keyboardSize: CGSize = (userInfo[UIKeyboardFrameBeginUserInfoKey]! as AnyObject).cgRectValue.size
let offset: CGSize = (userInfo[UIKeyboardFrameEndUserInfoKey]! as AnyObject).cgRectValue.size
if keyboardSize.height == offset.height {
if self.view.frame.origin.y == 0 {
UIView.animate(withDuration: 0.1, animations: { () -> Void in
self.view.frame.origin.y -= keyboardSize.height
})
}
} else {
UIView.animate(withDuration: 0.1, animations: { () -> Void in
self.view.frame.origin.y += keyboardSize.height - offset.height
})
}
}
}
问题
问题是编译器要求我将@objc 添加到我的keyboardWillShow 和keyboardWillHide 方法中。当我允许 Xcode 添加关键字时,编译器会立即要求我删除 @objc 关键字。
“#selector”的参数指的是实例方法“keyboardWillShow” 没有暴露给 Objective-C
我的问题
在这种情况下如何将keyboardWillShow 暴露给Objective-C?
或
有没有更好的方法来完成同样的任务?
【问题讨论】:
-
注意:与选择器无关,但您现在的方法将在 beta 6 中崩溃。您需要将其转换为 NSValue
(notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size -
@LeoDabus 这个确切的代码在我的 beta 6 视图控制器中完美运行
-
那很奇怪,我会仔细检查。当我更新到 beta 6 时,我的代码在转换为 AnyObject 时崩溃了
-
我想通了。您的方法有效,因为您首先要转换为 NSNotification。如果您不强制转换为 NSNotification 并且您需要按照我的建议进行操作,否则它会导致您的应用崩溃
-
您的屏幕截图显示您只导入 Foundation,但您知道需要导入 UIKit 才能在代码中使用
UIViewController。一些错误(包括缺少导入)可能会阻止 Xcode 进行代码分析,因此会显示旧的错误消息。
标签: xcode selector extension-methods swift3