用Swift键盘移动视图

我有一个应用程序在视图的下半部分有一个文本字段。 这意味着,当我去键入文本字段的键盘覆盖文本字段。

如何在打字时向上移动视图,以便我可以看到正在键入的内容,然后在键盘消失时将其移回原始位置?

我到处寻找,但所有的解决scheme似乎是在Obj-C,我还不能完全转换。

任何帮助将不胜感激。

这是一个解决scheme,不需要处理从一个textField到另一个textField的切换:

  override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil) } func keyboardWillShow(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { self.view.frame.origin.y -= keyboardSize.height } } func keyboardWillHide(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { self.view.frame.origin.y += keyboardSize.height } } 

为了解决这个问题,用这些keyboardWillShow/HidereplacekeyboardWillShow/Hide的两个function:

 func keyboardWillShow(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { if view.frame.origin.y == 0{ self.view.frame.origin.y -= keyboardSize.height } } } func keyboardWillHide(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { if view.frame.origin.y != 0 { self.view.frame.origin.y += keyboardSize.height } } } 

编辑SWIFT 3.0:

 override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil) } func keyboardWillShow(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { if self.view.frame.origin.y == 0{ self.view.frame.origin.y -= keyboardSize.height } } } func keyboardWillHide(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { if self.view.frame.origin.y != 0{ self.view.frame.origin.y += keyboardSize.height } } } 

在这个线程上的一个受欢迎的答案使用下面的代码:

 func keyboardWillShow(sender: NSNotification) { self.view.frame.origin.y -= 150 } func keyboardWillHide(sender: NSNotification) { self.view.frame.origin.y += 150 } 

有一个明显的问题,用静态的数量抵消你的看法。 它会在一个设备上看起来不错,但在任何其他大小的configuration上看起来都不好。 您需要获取键盘高度并将其用作偏移值。

这是一个适用于所有设备的解决scheme, 处理用户在input时隐藏预测文本字段的情况。

下面要注意的是,我们传递self.view.window作为我们的对象参数。 这将为我们提供来自我们的键盘的数据,比如它的高度!

 @IBOutlet weak var messageField: UITextField! override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: self.view.window) NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: self.view.window) } func keyboardWillHide(sender: NSNotification) { let userInfo: [NSObject : AnyObject] = sender.userInfo! let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size self.view.frame.origin.y += keyboardSize.height } 

我们会在所有设备上使它看起来不错,并处理用户添加或删除预测文本字段的情况。

 func keyboardWillShow(sender: NSNotification) { let userInfo: [NSObject : AnyObject] = sender.userInfo! let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size let offset: CGSize = userInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue.size if keyboardSize.height == offset.height { UIView.animateWithDuration(0.1, animations: { () -> Void in self.view.frame.origin.y -= keyboardSize.height }) } else { UIView.animateWithDuration(0.1, animations: { () -> Void in self.view.frame.origin.y += keyboardSize.height - offset.height }) } } 

删除观察员

在离开视图之前,不要忘记删除观察者,以防止不必要的消息被传输。

 override func viewWillDisappear(animated: Bool) { NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: self.view.window) NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: self.view.window) } 

根据评论的问题更新:

如果你有两个或更多的文本字段,你可以检查你的view.frame.origin.y是否为零。

 func keyboardWillShow(sender: NSNotification) { let userInfo: [NSObject : AnyObject] = sender.userInfo! let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size let offset: CGSize = userInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue.size if keyboardSize.height == offset.height { if self.view.frame.origin.y == 0 { UIView.animateWithDuration(0.1, animations: { () -> Void in self.view.frame.origin.y -= keyboardSize.height }) } } else { UIView.animateWithDuration(0.1, animations: { () -> Void in self.view.frame.origin.y += keyboardSize.height - offset.height }) } print(self.view.frame.origin.y) } 

video教程

将此添加到您的视图控制器。 奇迹般有效。 只需调整值。

 override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil); NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil); } func keyboardWillShow(sender: NSNotification) { self.view.frame.origin.y -= 150 } func keyboardWillHide(sender: NSNotification) { self.view.frame.origin.y += 150 } 

最简单的方法,甚至不需要任何代码:

  1. 下载KeyboardLayoutConstraint.swift并将文件添加(拖放)到您的项目中,如果您尚未使用Springanimation框架。
  2. 在故事板中,为View或Textfield创build底部约束,select约束(双击它),并在Identity Inspector中将其类从NSLayoutConstraint更改为KeyboardLayoutConstraint。
  3. 完成!

该对象将自动与键盘同步上移。

我看到所有的答案都是通过键盘高度的值来移动视图本身。 那么,我有一个详细的答案,如果你使用的约束,如自动autolayout ,可以通过改变其约束值(例如底部或顶部约束)移动一个预定义的值,或者您可以使用键盘大小的值,这可能是有用的。

在这个例子中,我使用从文本字段到底部布局视图的底部约束,初始值为175。

 @IBOutlet weak var bottomConstraint: NSLayoutConstraint! override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil); NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil); } func keyboardWillShow(notification: NSNotification) { //To retrieve keyboard size, uncomment following line //let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() bottomConstraint.constant = 260 UIView.animateWithDuration(0.3) { self.view.layoutIfNeeded() } } func keyboardWillHide(notification: NSNotification) { //To retrieve keyboard size, uncomment following line //let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() bottomConstraint.constant = 175 UIView.animateWithDuration(0.3) { self.view.layoutIfNeeded() } } 

我注意到,其他答案涉及从视图切割一些顶部。 如果你想简单地调整视图的大小而不削减任何内容,只要试试这个方法:)

 func keyboardWillShow(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { self.view.setTranslatesAutoresizingMaskIntoConstraints(true) self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.height - keyboardSize.height) } } func keyboardWillHide(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { self.collectionView.setTranslatesAutoresizingMaskIntoConstraints(false) self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.height + keyboardSize.height) } } 

对于Swift 3,我做了一个UIViewController子类,因为我需要在所有视图控制器中保持不变的行为。

 class SomeClassVC: UIViewController { //MARK: - Lifecycle override func viewDidLoad() { super.viewDidLoad() addKeyboardObservers() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) removeKeyboardObservers() } //MARK: - Overrides override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { view.endEditing(true) } //MARK: - Help func addKeyboardObservers() { NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil) } func removeKeyboardObservers() { NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: self.view.window) NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: self.view.window) } func keyboardWillShow(notification: NSNotification) { let keyboardHeight = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.height UIView.animate(withDuration: 0.1, animations: { () -> Void in self.view.window?.frame.origin.y = -1 * keyboardHeight! self.view.layoutIfNeeded() }) } func keyboardWillHide(notification: NSNotification) { UIView.animate(withDuration: 0.1, animations: { () -> Void in self.view.window?.frame.origin.y = 0 self.view.layoutIfNeeded() }) } func resignTextFieldFirstResponders() { for textField in self.view.subviews where textField is UITextField { textField.resignFirstResponder() } } func resignAllFirstResponders() { view.endEditing(true) } } 

我改进了其中一个答案,使其可以在一个页面上使用不同的键盘和不同的文本视图/字段:

添加观察员:

 override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange(notification:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil) } func keyboardWillHide() { self.view.frame.origin.y = 0 } func keyboardWillChange(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue { if YOURTEXTVIEW.isFirstResponder { self.view.frame.origin.y = -keyboardSize.height } } } 

删除观察员:

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

更新了Swift 3 …

正如其他人所说,你需要在控制器的viewDidLoad()方法中添加通知观察者,如下所示:

 NotificationCenter.default.addObserver(forName: .UIKeyboardWillShow, object: nil, queue: nil) { notification in self.keyboardWillShow(notification) } NotificationCenter.default.addObserver(forName: .UIKeyboardWillHide, object: nil, queue: nil) { notification in self.keyboardWillHide(notification) } NotificationCenter.default.addObserver(forName: .UIKeyboardDidShow, object: nil, queue: nil) { _ in self.enableUserInteraction() } NotificationCenter.default.addObserver(forName: .UIKeyboardDidHide, object: nil, queue: nil) { _ in self.enableUserInteraction() } 

记得在适当的时候删除你的观察者(我在viewWillDisappear()方法中做)

 NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil) NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil) NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidShow, object: nil) NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidHide, object: nil) 

然后,实现您的显示和隐藏方法 – 注意告诉应用程序忽略交互事件(beginIgnoringInteractionEvents)的行。 这是非常重要的,因为没有它,用户可能会点击一个字段,甚至滚动视图,导致转移发生第二次,导致可怕的UI故障。 在键盘显示和隐藏之前忽略交互事件将会阻止:

 func keyboardWillShow(notification: Notification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { UIApplication.shared.beginIgnoringInteractionEvents() self.view.frame.origin.y -= keyboardSize.height // add this line if you are shifting a scrollView, as in a chat application self.timelineCollectionView.contentInset.top += keyboardSize.height } } func keyboardWillHide(notification: Notification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { UIApplication.shared.beginIgnoringInteractionEvents() self.view.frame.origin.y += keyboardSize.height // add this line if you are shifting a scrollView, as in a chat application self.timelineCollectionView.contentInset.top -= keyboardSize.height } } 

最后,重新启用用户交互(请记住,此方法在键盘didShow或didHide之后触发):

 func enableUserInteraction() { UIApplication.shared.endIgnoringInteractionEvents() } 

这是我的解决scheme(实际上这个代码是在你的视图中没有文本域的情况下,这也适用于你有一个文本域的情况)

 class MyViewController: UIViewController, UITextFieldDelegate { @IBOutlet weak var firstTextField: UITextField! @IBOutlet weak var secondTextField: UITextField! var activeTextField: UITextField! var viewWasMoved: Bool = false override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(PrintViewController.keyboardWillShow(_:)), name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(PrintViewController.keyboardWillHide(_:)), name: UIKeyboardWillHideNotification, object: nil) } override func viewDidDisappear(animated: Bool) { super.viewWillDisappear(animated) NSNotificationCenter.defaultCenter().removeObserver(self) } func textFieldDidBeginEditing(textField: UITextField) { self.activeTextField = textField } func textFieldDidEndEditing(textField: UITextField) { self.activeTextField = nil } func textFieldShouldReturn(textField: UITextField) -> Bool { textField.resignFirstResponder() return true } func keyboardWillShow(notification: NSNotification) { let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() var aRect: CGRect = self.view.frame aRect.size.height -= keyboardSize!.height let activeTextFieldRect: CGRect? = activeTextField?.frame let activeTextFieldOrigin: CGPoint? = activeTextFieldRect?.origin if (!CGRectContainsPoint(aRect, activeTextFieldOrigin!)) { self.viewWasMoved = true self.view.frame.origin.y -= keyboardSize!.height } else { self.viewWasMoved = false } } func keyboardWillHide(notification: NSNotification) { if (self.viewWasMoved) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { self.view.frame.origin.y += keyboardSize.height } } } 

Swift 3代码

 var activeField: UITextField? override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(ProfileViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(ProfileViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil) } func textFieldDidBeginEditing(_ textField: UITextField){ activeField = textField } func textFieldDidEndEditing(_ textField: UITextField){ activeField = nil } func keyboardWillShow(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { if (self.activeField?.frame.origin.y)! >= keyboardSize.height { self.view.frame.origin.y = keyboardSize.height - (self.activeField?.frame.origin.y)! } else { self.view.frame.origin.y = 0 } } } func keyboardWillHide(notification: NSNotification) { self.view.frame.origin.y = 0 } 

如果在同一个VC上有两个或两个以上的文本字段,用户点击其中一个,然后点击另一个,而不调用keyboardWillHide函数,则视图向上再一次,这是不必要的,因为你将拥有键盘,一个有键盘高度的空白区域,然后是使用我编辑的答案中的代码的视图:

 override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil) } func keyboardWillShow(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { self.view.frame.origin.y -= keyboardSize.height } } func keyboardWillHide(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { self.view.frame.origin.y += keyboardSize.height } } 

为了解决这个问题,将这两个函数“KeyboardWillShow / Hide”replace为这些:

 func keyboardWillShow(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { if view.frame.origin.y == 0{ self.view.frame.origin.y -= keyboardSize.height } } } func keyboardWillHide(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { if view.frame.origin.y != 0 { self.view.frame.origin.y += keyboardSize.height } } } 

对于Swift 3

 func textFieldDidBeginEditing(_ textField: UITextField) { // became first responder //move textfields up let myScreenRect: CGRect = UIScreen.main.bounds let keyboardHeight : CGFloat = 216 UIView.beginAnimations( "animateView", context: nil) var movementDuration:TimeInterval = 0.35 var needToMove: CGFloat = 0 var frame : CGRect = self.view.frame if (textField.frame.origin.y + textField.frame.size.height + UIApplication.shared.statusBarFrame.size.height > (myScreenRect.size.height - keyboardHeight - 30)) { needToMove = (textField.frame.origin.y + textField.frame.size.height + UIApplication.shared.statusBarFrame.size.height) - (myScreenRect.size.height - keyboardHeight - 30); } frame.origin.y = -needToMove self.view.frame = frame UIView.commitAnimations() } func textFieldDidEndEditing(_ textField: UITextField) { //move textfields back down UIView.beginAnimations( "animateView", context: nil) var movementDuration:TimeInterval = 0.35 var frame : CGRect = self.view.frame frame.origin.y = 0 self.view.frame = frame UIView.commitAnimations() } 

这个function已经在Ios里build立起来了,但是我们需要做外部的事情。
插入下面的代码
*当textField在键盘下时移动视图,
* textField在键盘上方时不移动视图
*需要时根据键盘的高度移动视图。
这在所有情况下都可以工作和testing。

 import UIKit class NamVcc: UIViewController, UITextFieldDelegate { @IBOutlet weak var NamTxtBoxVid: UITextField! var VydTxtBoxVar: UITextField! var ChkKeyPadDspVar: Bool = false var KeyPadHytVal: CGFloat! override func viewDidLoad() { super.viewDidLoad() NamTxtBoxVid.delegate = self } override func viewWillAppear(animated: Bool) { NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(TdoWenKeyPadVyd(_:)), name:UIKeyboardWillShowNotification, object: nil); NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(TdoWenKeyPadHyd(_:)), name:UIKeyboardWillHideNotification, object: nil); } func textFieldDidBeginEditing(TxtBoxPsgVar: UITextField) { self.VydTxtBoxVar = TxtBoxPsgVar } func textFieldDidEndEditing(TxtBoxPsgVar: UITextField) { self.VydTxtBoxVar = nil } func textFieldShouldReturn(TxtBoxPsgVar: UITextField) -> Bool { self.VydTxtBoxVar.resignFirstResponder() return true } override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { view.endEditing(true) super.touchesBegan(touches, withEvent: event) } func TdoWenKeyPadVyd(NfnPsgVar: NSNotification) { if(!self.ChkKeyPadDspVar) { self.KeyPadHytVal = (NfnPsgVar.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().height var NonKeyPadAraVar: CGRect = self.view.frame NonKeyPadAraVar.size.height -= self.KeyPadHytVal let VydTxtBoxCenVal: CGPoint? = VydTxtBoxVar?.frame.origin if (!CGRectContainsPoint(NonKeyPadAraVar, VydTxtBoxCenVal!)) { self.ChkKeyPadDspVar = true UIView.animateWithDuration(1.0, animations: { self.view.frame.origin.y -= (self.KeyPadHytVal)}, completion: nil) } else { self.ChkKeyPadDspVar = false } } } func TdoWenKeyPadHyd(NfnPsgVar: NSNotification) { if (self.ChkKeyPadDspVar) { self.ChkKeyPadDspVar = false UIView.animateWithDuration(1.0, animations: { self.view.frame.origin.y += (self.KeyPadHytVal)}, completion: nil) } } override func viewDidDisappear(animated: Bool) { super.viewWillDisappear(animated) NSNotificationCenter.defaultCenter().removeObserver(self) view.endEditing(true) ChkKeyPadDspVar = false } } 

| :: | 有时视图会下降,在这种情况下使用高度+/- 150:

  NonKeyPadAraVar.size.height -= self.KeyPadHytVal + 150 { self.view.frame.origin.y -= self.KeyPadHytVal - 150}, completion: nil) { self.view.frame.origin.y += self.KeyPadHytVal - 150}, completion: nil) 
 func keyboardWillShow(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { self.view.frame.origin.y = self.view.frame.height - (self.view.frame.height + keyboardSize.height) } } func keyboardWillHide(notification: NSNotification) { self.view.frame.origin.y = 0 } 

它必须更稳定

  override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil) } // MARK: - keyboard func keyboardWillShow(notification: NSNotification) { if let userInfo = notification.userInfo { if let keyboardSize = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { let contentInsets = self.tblView.contentInset as UIEdgeInsets self.tblView.contentInset = UIEdgeInsets(top: contentInsets.top, left: contentInsets.left, bottom: keyboardSize.height, right:contentInsets.right) // ... } else { // no UIKeyboardFrameBeginUserInfoKey entry in userInfo } } else { // no userInfo dictionary in notification } } func keyboardWillHide(notification: NSNotification) { let contentInsets = self.tblView.contentInset as UIEdgeInsets self.tblView.contentInset = UIEdgeInsets(top: contentInsets.top, left: contentInsets.left, bottom: 0, right:contentInsets.right) } 

使用以下代码查看UITextField点击

 func textFieldDidBeginEditing(textField: UITextField) { ViewUpanimateMoving(true, upValue: 100) } func textFieldDidEndEditing(textField: UITextField) { ViewUpanimateMoving(false, upValue: 100) } func ViewUpanimateMoving (up:Bool, upValue :CGFloat){ var durationMovement:NSTimeInterval = 0.3 var movement:CGFloat = ( up ? -upValue : upValue) UIView.beginAnimations( "animateView", context: nil) UIView.setAnimationBeginsFromCurrentState(true) UIView.setAnimationDuration(durationMovement) self.view.frame = CGRectOffset(self.view.frame, 0, movement) UIView.commitAnimations() } 

我做了一个椰子树来简化这个事情:

https://github.com/xtrinch/KeyboardLayoutHelper

如何使用它:

创build一个自动布局的底部约束,在模块KeyboardLayoutHelper中给它一个KeyboardLayoutConstraint的类,并且该窗格将完成必要的工作,以增加它以适应出现和消失的键盘。 请参阅示例项目有关如何使用它的示例(我做了两个:scrollView内的textFields和两个基本视图垂直居中的textField – login和注册)。

底部布局约束可以是容器视图,textField本身,任何东西,你的名字。

 func registerForKeyboardNotifications() { //Keyboard NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWasShown), name: UIKeyboardDidShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillBeHidden), name: UIKeyboardDidHideNotification, object: nil) } func deregisterFromKeyboardNotifications(){ NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil) } func keyboardWasShown(notification: NSNotification){ let userInfo: NSDictionary = notification.userInfo! let keyboardInfoFrame = userInfo.objectForKey(UIKeyboardFrameEndUserInfoKey)?.CGRectValue() let windowFrame:CGRect = (UIApplication.sharedApplication().keyWindow!.convertRect(self.view.frame, fromView:self.view)) let keyboardFrame = CGRectIntersection(windowFrame, keyboardInfoFrame!) let coveredFrame = UIApplication.sharedApplication().keyWindow!.convertRect(keyboardFrame, toView:self.view) let contentInsets = UIEdgeInsetsMake(0, 0, (coveredFrame.size.height), 0.0) self.scrollViewInAddCase .contentInset = contentInsets; self.scrollViewInAddCase.scrollIndicatorInsets = contentInsets; self.scrollViewInAddCase.contentSize = CGSizeMake((self.scrollViewInAddCase.contentSize.width), (self.scrollViewInAddCase.contentSize.height)) } /** this method will fire when keyboard was hidden - parameter notification: contains keyboard details */ func keyboardWillBeHidden (notification: NSNotification) { self.scrollViewInAddCase.contentInset = UIEdgeInsetsZero self.scrollViewInAddCase.scrollIndicatorInsets = UIEdgeInsetsZero } 

swift 3.0 insert in viewDidLoad(), this->

{

view.addSubview(Your_messageInputConteinerView)

  view.addConstraintWithFormat(format: "H:|[v0]|", views:Your_messageInputConteinerView) view.addConstraintWithFormat(format: "V:[v0(48)]", views:Your_messageInputConteinerView) 

NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification(notification:)), name: .UIKeyboardWillHide, object: nil)

 bottomConstraint = NSLayoutConstraint(item: Your_messageInputConteinerView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0) view.addConstraint(bottomConstraint!) 

}

func handleKeyboardNotification(notification:Notification){

 if let userInfo = notification.userInfo { if let keyBoardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue{ print(keyBoardFrame) if bottomConstraint?.constant != CGFloat(0) { bottomConstraint?.constant = 0 return } bottomConstraint?.constant = -keyBoardFrame.height or self.view.frame.origin.y = -keyBoardFrame.height } } 

}

i've read answers and solved my problem by this lines of code:

 class ViewController: UIViewController, UITextFieldDelegate { @IBOutlet weak var titleField: UITextField! @IBOutlet weak var priceField: UITextField! @IBOutlet weak var detailsField: UTtextField! override func viewDidLoad() { super.viewDidLoad() // Do not to forget to set the delegate otherwise the textFieldShouldReturn(_:) // won't work and the keyboard will never be hidden. priceField.delegate = self titleField.delegate = self detailsField.delegate = self NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil) } func textFieldShouldReturn(_ textField: UITextField) -> Bool { self.view.endEditing(true) return false } func keyboardWillShow(notification: NSNotification) { var translation:CGFloat = 0 if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { if detailsField.isEditing{ translation = CGFloat(-keyboardSize.height) }else if priceField.isEditing{ translation = CGFloat(-keyboardSize.height / 3.8) } } UIView.animate(withDuration: 0.2) { self.view.transform = CGAffineTransform(translationX: 0, y: translation) } } func keyboardWillHide(notification: NSNotification) { UIView.animate(withDuration: 0.2) { self.view.transform = CGAffineTransform(translationX: 0, y: 0) } } } 

I have a few UITextFields and want the view to move up differently depending on which textField is tapped.

if you are like me who has tried all the above solutions and still your problem is not solved, I have a got a great solution for you that works like a charm. First I want clarify few things about some of solutions mentioned above.

  1. In my case IQkeyboardmanager was working only when there is no auto layout applied on the elements, if it is applied then IQkeyboard manager will not work the way we think.
  2. Same thing with upward movement of self.view .
  3. i have wriiten a objective c header with a swift support for pushing UITexfield upward when user clicks on it, solving the problem of keyboard covering the UITextfield : https://github.com/coolvasanth/smart_keyboard .
  4. One who has An intermediate or higher level in iOS app development can easily understand the repository and implement it. 祝一切顺利

My two cents for beginners: in above samples someone changes coordinates, other uses "autoresizing mask", and other constraints:

As Apple says, do not mix these 3 types of logic. If You have constraints in Storyboard, do not try to change x/y. It definitively not work.

this video tutorial is the best. 7 mins long and it'll just make so much sense. Such a simple solution for when you have multiple text fields and want the scroll view to move "x" amount of pixels when that specific textfield is tapped.

https://youtu.be/VuiPGJOEBH4

Just these steps:

-Place all your textfields within a scrollview that is constrained to the edges of the view.

-Connect all the textfields and scroll view as delegates to the view controller.

-Connect all textfields and scroll view with an IBOutlet.

 class ViewController: UIViewController, UITextFieldDelegate { 

-Add UITextFieldDelegate protocol to your class

 @IBOutlet var stateAddress: UITextField! @IBOutlet var zipAddress: UITextField! @IBOutlet var phoneNumber: UITextField! @IBOutlet var vetEmailAddress: UITextField! @IBOutlet weak var scrollView: UIScrollView! 

-Add UITextFieldDelegate methods to your swift file:

 func textFieldShouldReturn(textField: UITextField) -> Bool { textField.resignFirstResponder() return true } func textFieldDidBeginEditing(textField: UITextField) { if (textField == self.stateAddress) { scrollView.setContentOffset(CGPointMake(0, 25), animated: true) } else if (textField == self.zipAddress) { scrollView.setContentOffset(CGPointMake(0, 57), animated: true) } else if (textField == self.phoneNumber) { scrollView.setContentOffset(CGPointMake(0, 112), animated: true) } else if (textField == self.vetEmailAddress) { scrollView.setContentOffset(CGPointMake(0, 142), animated: true) } } func textFieldDidEndEditing(textField: UITextField) { scrollView.setContentOffset(CGPointMake(0, 0), animated: true) } 

The first method just activates the return button on the keyboard to dismiss the keyboard. The second is when you tap into whatever specific textfield then setting the y offset of how far your scrollview scrolls (mine is based off of the y location on my view controllers 25,57,112,142). The last says when you tap away from the keyboard the scrollview goes back to original location.

I made my view pixel perfect this way!