这是在键盘出现时滑动屏幕的过程,但是许多控制器都描述了此过程。 if和else中的处理根据每个控制器而变化。 有没有办法干净地共享它? 另外,我们应该在哪里以及如何进行共通?
func keyboardWillChangeFrame(_ notification: Notification) {
if let endFrame = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
var keyboardHeight = UIScreen.main.bounds.height - endFrame.origin.y
if #available(iOS 11, *) {
if keyboardHeight > 0 {
view.addGestureRecognizer(ui.viewTapGesture)
ui.isHiddenSubmitBtn(false)
ui.isHiddenTextCount(false)
keyboardHeight = keyboardHeight - view.safeAreaInsets.bottom + ui.submitBtn.frame.height + 8
} else {
view.removeGestureRecognizer(ui.viewTapGesture)
ui.isHiddenSubmitBtn(true)
ui.isHiddenTextCount(true)
}
}
ui.textViewBottomConstraint.constant = -keyboardHeight - 8
view.layoutIfNeeded()
}
}
答案 0 :(得分:4)
您可以使用类和协议,例如下面的示例代码
// Firstly Create Notifier Keyboard
class KeyboardNotifier: NSObject {
// We notify this closures
var keyboardPresent: ((_ height: CGFloat) -> Void)?
var keyboardDismiss: ((_ height: CGFloat) -> Void)?
// Add Notification
func listenKeyboard() {
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardWillChangeFramex(_:)),
name: UIApplication.keyboardWillChangeFrameNotification,
object: nil)
}
// Handle Notification and call closures
@objc func keyboardWillChangeFramex(_ notification: Notification) {
if let endFrame = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
let keyboardHeight = UIScreen.main.bounds.height - endFrame.origin.y
if #available(iOS 11, *) {
DispatchQueue.main.async { [weak self] in
if keyboardHeight > 0 {
self?.keyboardPresent?(keyboardHeight)
} else {
self?.keyboardDismiss?(keyboardHeight)
}
}
}
}
}
}
// Create a listener protocol
protocol KeyboardListener {
func keyboardPresent(_ height: CGFloat)
func keyboardDismiss(_ height: CGFloat)
var keyboardNotifier: KeyboardNotifier! { get set }
}
// We need a extension for we don't want all viewController
extension KeyboardListener where Self: UIViewController {
// We need call this function viewDidLoad later
func listenKeyboard(keyboardNotifier: KeyboardNotifier) {
keyboardNotifier.keyboardDismiss = { [weak self] height in
self?.keyboardDismiss(height)
}
keyboardNotifier.keyboardPresent = { [weak self] height in
self?.keyboardPresent(height)
}
}
}
// A XViewController want's to listen keyboard
class XViewController: UIViewController, KeyboardListener {
var keyboardNotifier: KeyboardNotifier!
override func viewDidLoad() {
super.viewDidLoad()
// We need instance for life cycle
keyboardNotifier = KeyboardNotifier()
listenKeyboard(keyboardNotifier: keyboardNotifier)
}
func keyboardPresent(_ height: CGFloat) {
// TODO UI
}
func keyboardDismiss(_ height: CGFloat) {
// TODO UI
}
}
// If you want all viewController listen keyboard
class BaseViewController: UIViewController, KeyboardListener {
var keyboardNotifier: KeyboardNotifier!
override func viewDidLoad() {
super.viewDidLoad()
// We need instance for life cycle
keyboardNotifier = KeyboardNotifier()
listenKeyboard(keyboardNotifier: keyboardNotifier)
}
func keyboardPresent(_ height: CGFloat) {
}
func keyboardDismiss(_ height: CGFloat) {
}
}
// This Y ViewController from BaseViewController
class YViewController: BaseViewController {
override func keyboardPresent(_ height: CGFloat) {
}
override func keyboardDismiss(_ height: CGFloat) {
}
}