Ios Swift:来自UIViewController扩展的RegisterWorkeryBoardNotification

Ios Swift:来自UIViewController扩展的RegisterWorkeryBoardNotification,ios,swift,keyboard,Ios,Swift,Keyboard,我正在尝试清理代码,创建并扩展到UIViewController,以注册和注销我的键盘。在我的实用程序文件中,我有以下内容: extension UIViewController { //Register the keyboard for notifications in viewDidLoad func registerForKeyboardNotifications() { //Adding notifies on keyboard appearin

我正在尝试清理代码,创建并扩展到
UIViewController
,以注册和注销我的键盘。在我的实用程序文件中,我有以下内容:

extension UIViewController {
     //Register the keyboard for notifications in  viewDidLoad
     func registerForKeyboardNotifications() {

         //Adding notifies on keyboard appearing
         NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(CreateEventVC.keyboardWasShown(_:)), name: UIKeyboardWillShowNotification, object: nil) 
         NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(CreateEventVC.keyboardWillBeHidden(_:)), name: UIKeyboardWillHideNotification, object: nil)

     }

     //Deregister the keyboard for notification in viewWillDisapper
     func deregisterFromKeyboardNotifications() {

         //Removing notifies on keyboard appearing
         NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
         NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
     }
}
我需要的是
选择器中的“CreateEventVC”作为当前

然后我在我的ViewController中调用它,如下所示:

override func viewDidLoad() {
         super.viewDidLoad()

         //Register Keyboard
         registerForKeyboardNotifications()
}

override func viewWillDisappear(animated: Bool) {

    deregisterFromKeyboardNotifications()

}

func keyboardWasShown(notification: NSNotification) {

    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {

        self.view.frame.origin.y -= keyboardSize.height

    }

}

func keyboardWillBeHidden(notification: NSNotification) {

    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {

        self.view.frame.origin.y += keyboardSize.height

    }

}

我觉得这不是最好的做法。任何帮助或建议都会很好

我正在使用
UIViewController
UIScrollView
扩展。如果要移动
UIView
,也可以使用此扩展,但使用
UIScrollView
更方便,因为它不会弄乱视图边界,并且如果需要添加更多文本字段,这种方法更通用

extension UIViewController {
    func registerForKeyboardDidShowNotification(usingBlock block: ((NSNotification, CGSize) -> Void)? = nil) {
        NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardDidShowNotification, object: nil, queue: nil, usingBlock: { (notification) -> Void in
            let userInfo = notification.userInfo!
            guard let keyboardSize = userInfo[UIKeyboardFrameBeginUserInfoKey]?.CGRectValue.size else { fatalError("Can't grab the keyboard frame") }

            block?(notification, keyboardSize)
        })
    }

    func registerForKeyboardWillHideNotification(usingBlock block: (NSNotification -> Void)? = nil) {
        NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardWillHideNotification, object: nil, queue: nil, usingBlock: { (notification) -> Void in
            block?(notification)
        })
    }
}
因此,使用这段代码,在您的
UIViewController
viewDidLoad()
方法中,您可以注册键盘通知,并在块中添加任何附加函数。像这样:

override func viewDidLoad() {
    super.viewDidLoad()

    registerForKeyboardDidShowNotification { notif, size in
        self.view.frame.origin.y -= size.height
    }

    registerForKeyboardWillHideNotification { notif in
        self.view.frame.origin.y = 0
    }
}

编辑:(对于
UIScrollView
) 1) 你能用动画显示键盘吗

实际上,键盘的外观总是动画的,所以我想你说的是滚动视图的调整。是的,你可以。下面我发布了更新的
UIViewController
UIScrollView
扩展,它们正在处理这个问题

2) 我需要注销键盘吗

好吧,这是一个很好的实践,以避免在未来的崩溃。为此,您可能更愿意在
视图中添加通知,并在
视图中删除通知

    NSNotificationCenter.defaultCenter().removeObserver(scrollView, name: UIKeyboardDidShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().removeObserver(scrollView, name: UIKeyboardWillHideNotification, object: nil)
3) 对于UIScrollView方法,我会将所有对象放在屏幕的滚动视图中,然后在每个UITextField成为第一响应程序时以编程方式滚动视图吗

您不会以编程方式滚动任何内容。您需要做的是更改
UIScrollView
的插入,它将自动使第一响应者在屏幕上可见

这是我在项目中使用的代码:

extension UIViewController {
    func registerForKeyboardDidShowNotification(scrollView: UIScrollView, usingBlock block: (CGSize? -> Void)? = nil) {
        NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardDidShowNotification, object: nil, queue: nil, usingBlock: { (notification) -> Void in
            let userInfo = notification.userInfo!
            let keyboardSize = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue.size
            let contentInsets = UIEdgeInsetsMake(scrollView.contentInset.top, scrollView.contentInset.left, keyboardSize!.height, scrollView.contentInset.right)

            scrollView.setContentInsetAndScrollIndicatorInsets(contentInsets)
            block?(keyboardSize)
        })
    }

    func registerForKeyboardWillHideNotification(scrollView: UIScrollView, usingBlock block: (Void -> Void)? = nil) {
        NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardWillHideNotification, object: nil, queue: nil, usingBlock: { (notification) -> Void in
            let contentInsets = UIEdgeInsetsMake(scrollView.contentInset.top, scrollView.contentInset.left, 0, scrollView.contentInset.right)
            scrollView.setContentInsetAndScrollIndicatorInsets(contentInsets)
            block?()
        })
    }
}



extension UIScrollView {
    func setContentInsetAndScrollIndicatorInsets(edgeInsets: UIEdgeInsets) {
        self.contentInset = edgeInsets
        self.scrollIndicatorInsets = edgeInsets
    }
}
在您的
视图中将出现
方法,只需按如下方式添加它:

registerForKeyboardWillShowNotification(scrollView)
registerForKeyboardWillHideNotification(scrollView)

每当键盘出现时,它将收缩scrollview的contentInset;每当键盘消失时,它将展开scrollview。

以下是Swift 4扩展,其中有一种方法需要将约束放入其中:

import UIKit

extension UIViewController {

    func bindKeypad(to constraint: NSLayoutConstraint) {
        NotificationCenter.default.addObserver(forName: Notification.Name.UIKeyboardWillShow, object: nil, queue: OperationQueue.main) { [weak self, weak constraint] notification in
            guard let info = notification.userInfo else { return }
            guard let height = (info[UIKeyboardFrameEndUserInfoKey] as? CGRect)?.size.height else { return }
            guard constraint?.constant != height else { return }
            constraint?.constant = height
            self?.view.layoutIfNeeded()

        }

        NotificationCenter.default.addObserver(forName: Notification.Name.UIKeyboardWillHide, object: nil, queue: OperationQueue.main) { [weak self, weak constraint] _ in
            guard constraint?.constant != 0 else { return }
            constraint?.constant = 0
            self?.view.layoutIfNeeded()
        }
    }
}
在你们班上的Denit call上:

deinit {
        NotificationCenter.default.removeObserver(self)
    }
要在viewDidLoad中使用它,请执行以下操作:

bindKeypad(to: bottomKeypadConstraint)

我认为我们可以创建包含键盘事件的BaseController,我们必须从中继承viewController,并覆盖像viewWiillAppear这样的键盘方法(键盘将出现或键盘将消失)

要求

class BaseController: UIViewController {
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow(notification:)), name: .UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillHide(notification:)), name: .UIKeyboardWillHide, object: nil)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
        NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
    }

    //****************************************************
    //MARK: - Keyboard event listener
    //****************************************************

    @objc func keyBoardWillShow(notification: NSNotification) {
       //Override this method
    }

    @objc func keyBoardWillHide(notification: NSNotification) {
        //Override this method
    }
}
如何使用

class ViewController:BaseController {
    override func keyBoardWillHide(notification: NSNotification) {
        // Do something
    }
    override func keyBoardWillShow(notification: NSNotification) {
        // Do something
    }
}

谢谢你的回答。几个问题:1)你能为键盘显示动画吗?2) 我需要注销键盘吗?3) 对于
UIScrollView
方法,当每个
UITextField
成为第一响应者时,我会将所有对象放在屏幕的滚动视图中,然后通过编程滚动视图吗?再次感谢@Manstof好的,我将更新我的
UIScrollView
的答案。我一直在使用您提供的所有答案,
UIScrollView
工作得最好!谢谢谢谢你@noir。这解决了我的目的。考虑把它转换成最新的SWIFT语法。做了一个编辑,在等待评论:但是调用Suff.VIEW会出现在VIEWS WORKWORD函数中会引起一些棘手的问题。所以你可能不想复制粘贴这个.Yo@adams.s thnx