关于干净的常用方法

时间:2019-07-11 15:48:11

标签: swift

这是在键盘出现时滑动屏幕的过程,但是许多控制器都描述了此过程。 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()
    }
}

1 个答案:

答案 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) {

    }
}