[英]How to call a function from an extension to UIViewController in Swift
[英]Swift: registerForKeyboardNotifications from UIViewController extension
我正在尝试清理我的代码并创建和扩展到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
}
}
我觉得这不是最好的做法。 任何帮助或建议都会很棒!
我正在使用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)你能为键盘显示动画吗?
实际上键盘外观总是动画的,所以我认为你说的是scrollview调整。 是的你可以。 下面我发布了更新的UIViewController
和UIScrollView
扩展,它们正在处理它。
2)我是否需要取消注册键盘?
那么,避免将来发生崩溃是一种很好的做法。 为此,您可能更愿意在viewWillAppear
添加通知,并在viewWillDisappear
方法中将其删除。
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
}
}
在viewWillAppear
方法中,只需添加如下:
registerForKeyboardWillShowNotification(scrollView)
registerForKeyboardWillHideNotification(scrollView)
每当键盘出现时它都会缩小scrollview的contentInset,并在键盘消失时展开它。
我想我们可以创建包含键盘事件的BaseController,我们必须从它继承viewController并覆盖viewWiillAppear(keyboardWillAppear或keyboardWillDisappear)等键盘方法
需求量的
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
}
}
这是Swift 4扩展,其中包含一个需要将Constraint放入其中的方法:
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()
}
}
}
在你的课堂上有deinit电话:
deinit {
NotificationCenter.default.removeObserver(self)
}
在viewDidLoad中使用它调用:
bindKeypad(to: bottomKeypadConstraint)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.