ios - Swift:来自 UIViewController 扩展的 registerForKeyboardNotifications

标签 ios swift keyboard

我正在尝试清理我的代码并创建和扩展 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)
     }
}

我需要的是 selector 中的“CreateEventVC”成为当前 Class

然后我在我的 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

    }

}

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

最佳答案

我正在使用 UIViewControllerUIScrollView 扩展。如果你要移动你的 UIView 你也可以使用这个扩展,但是使用 UIScrollView 更方便,因为它不会弄乱你的 View 边界,以防你需要要添加更多文本字段,这种方法更通用。

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)
        })
    }
}

因此,使用此代码,在您的 UIViewControllerviewDidLoad() 方法中,您可以注册键盘通知并在 block 中添加任何其他功能。像这样:

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)Can you animate the keyboard showing?

实际上键盘外观始终是动画的,所以我认为您是在谈论 ScrollView 调整。是的你可以。下面我发布了更新的 UIViewControllerUIScrollView 扩展,它们正在处理这个问题。

2) Do i need to deregister the keyboard?

好吧,这是避免将来发生崩溃的好习惯。为此,您可能更愿意在 viewWillAppear 方法中添加您的通知,并在 viewWillDisappear 方法中删除它。

    NSNotificationCenter.defaultCenter().removeObserver(scrollView, name: UIKeyboardDidShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().removeObserver(scrollView, name: UIKeyboardWillHideNotification, object: nil)

3) For the UIScrollView method would I put all my objects in a scroll view in the screen then just programmatically scroll the view when each UITextField becomes the first responder?

您不会以编程方式滚动任何内容。您需要做的是更改 UIScrollView 的 insets,它会自动使 firstResponder 在屏幕上可见。

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

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
    }
}

在您的viewWillAppear 方法中,只需像这样添加它:

registerForKeyboardWillShowNotification(scrollView)
registerForKeyboardWillHideNotification(scrollView)

它会在键盘出现时缩小 ScrollView 的 contentInset,并在键盘消失时展开它。

关于ios - Swift:来自 UIViewController 扩展的 registerForKeyboardNotifications,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37621144/

相关文章:

ios - Spritekit- DidBeginContact 未被调用

ios - 下载视频并将其保存到相机胶卷

iphone - 在ios中使用自定义键盘的问题

ios - 为什么要使用 resignFirstResponder()

jquery - 在 jQuery 中组合键码事件

ios - 使用复制属性会导致段错误

ios - 如何获得准确的电池电量?

objective-c - 等待方法在 iOS 中完成

ios - 如何在 Swift 中封装 UIViewController(如 UIAlertController)?

ios - 从通知对象传递数组会导致 iOS 10 中的应用程序崩溃