teclado tamaño como cambiar aumentar acomodar ios swift cocoa-touch keyboard uitextfield

ios - tamaño - como acomodar el teclado del ipad



Mover el campo de texto cuando el teclado aparece rápido (29)

I have done by following manner:

This is useful when textfield superview is view

class AdminLoginViewController: UIViewController, UITextFieldDelegate{ @IBOutlet weak var txtUserName: UITextField! @IBOutlet weak var txtUserPassword: UITextField! @IBOutlet weak var btnAdminLogin: UIButton! private var activeField : UIView? var param:String! var adminUser : Admin? = nil var kbHeight: CGFloat! override func viewDidLoad() { self.addKeyBoardObserver() self.addGestureForHideKeyBoard() } override func viewWillDisappear(animated: Bool) { super.viewWillDisappear(animated) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } func addGestureForHideKeyBoard() { let tapGesture = UITapGestureRecognizer(target: self, action: Selector("hideKeyboard")) tapGesture.cancelsTouchesInView = false view.addGestureRecognizer(tapGesture) } func hideKeyboard() { self.view.endEditing(true) } func addKeyBoardObserver(){ NSNotificationCenter.defaultCenter().addObserver(self, selector: "willChangeKeyboardFrame:", name:UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: "willChangeKeyboardFrame:", name:UIKeyboardWillHideNotification, object: nil) } func removeObserver(){ NSNotificationCenter.defaultCenter().removeObserver(self) } //MARK:- textfiled Delegate func textFieldShouldBeginEditing(textField: UITextField) -> Bool { activeField = textField return true } func textFieldShouldEndEditing(textField: UITextField) -> Bool { if activeField == textField { activeField = nil } return true } func textFieldShouldReturn(textField: UITextField) -> Bool { if txtUserName == textField { txtUserPassword.becomeFirstResponder() } else if (textField == txtUserPassword) { self.btnAdminLoginAction(nil) } return true; } func willChangeKeyboardFrame(aNotification : NSNotification) { if self.activeField != nil && self.activeField!.isFirstResponder() { if let keyboardSize = (aNotification.userInfo![UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { let dy = (self.activeField?.superview?.convertRect((self.activeField?.frame)!, toView: view).origin.y)! let height = (self.view.frame.size.height - keyboardSize.size.height) if dy > height { var frame = self.view.frame frame.origin.y = -((dy - height) + (self.activeField?.frame.size.height)! + 20) self.view.frame = frame } } } else { var frame = self.view.frame frame.origin.y = 0 self.view.frame = frame } } }

Estoy usando Swift para programar con iOS y estoy usando este código para mover el UITextField , pero no funciona. Llamo a la función keyboardWillShow correctamente, pero el campo de texto no se mueve. Estoy usando autolayout.

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); } deinit { NSNotificationCenter.defaultCenter().removeObserver(self); } func keyboardWillShow(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { //let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0) var frame = self.ChatField.frame frame.origin.y = frame.origin.y - keyboardSize.height + 167 self.chatField.frame = frame println("asdasd") } }


Aquí está mi versión para una solución para Swift 2.2:

Primero regístrese para Mostrar / Ocultar notificaciones de teclado

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(MessageThreadVC.keyboardWillShow(_:)), name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(MessageThreadVC.keyboardWillHide(_:)), name: UIKeyboardWillHideNotification, object: nil)

Luego, en los métodos correspondientes a esas notificaciones, mueva la vista principal hacia arriba o hacia abajo

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

El truco está en la parte "keyboardWillShow" que recibe llamadas cada vez que "QuickType Suggestion Bar" se expande o contrae. Entonces siempre establecemos la coordenada y de la vista principal, que es igual al valor negativo de la altura total del teclado (con o sin la parte de la "Barra de tipos rápidos").

Al final no te olvides de eliminar observadores

deinit { NSNotificationCenter.defaultCenter().removeObserver(self) }


Creé un protocolo Swift 3 para manejar la apariencia / desaparición del teclado

import UIKit protocol KeyboardHandler: class { var bottomConstraint: NSLayoutConstraint! { get set } func keyboardWillShow(_ notification: Notification) func keyboardWillHide(_ notification: Notification) func startObservingKeyboardChanges() func stopObservingKeyboardChanges() } extension KeyboardHandler where Self: UIViewController { func startObservingKeyboardChanges() { // NotificationCenter observers NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillShow, object: nil, queue: nil) { [weak self] notification in self?.keyboardWillShow(notification) } // Deal with rotations NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil, queue: nil) { [weak self] notification in self?.keyboardWillShow(notification) } // Deal with keyboard change (emoji, numerical, etc.) NotificationCenter.default.addObserver(forName: NSNotification.Name.UITextInputCurrentInputModeDidChange, object: nil, queue: nil) { [weak self] notification in self?.keyboardWillShow(notification) } NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillHide, object: nil, queue: nil) { [weak self] notification in self?.keyboardWillHide(notification) } } func keyboardWillShow(_ notification: Notification) { let verticalPadding: CGFloat = 20 // Padding between the bottom of the view and the top of the keyboard guard let value = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return } let keyboardHeight = value.cgRectValue.height // Here you could have more complex rules, like checking if the textField currently selected is actually covered by the keyboard, but that''s out of this scope. self.bottomConstraint.constant = keyboardHeight + verticalPadding UIView.animate(withDuration: 0.1, animations: { () -> Void in self.view.layoutIfNeeded() }) } func keyboardWillHide(_ notification: Notification) { self.bottomConstraint.constant = 0 UIView.animate(withDuration: 0.1, animations: { () -> Void in self.view.layoutIfNeeded() }) } func stopObservingKeyboardChanges() { NotificationCenter.default.removeObserver(self) } }

Then, to implement it in a UIViewController, do the following:

  • let the viewController conform to this protocol :

    class FormMailVC: UIViewControlle, KeyboardHandler {

  • start observing keyboard changes in viewWillAppear:

    // MARK: - View controller life cycle override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) startObservingKeyboardChanges() }

  • stop observing keyboard changes in viewWillDisappear:

    override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) stopObservingKeyboardChanges() }

  • create an IBOutlet for the bottom constraint from the storyboard:

    // NSLayoutConstraints @IBOutlet weak var bottomConstraint: NSLayoutConstraint!

    (I recommend having all of your UI embedded inside a "contentView", and linking to this property the bottom constraint from this contentView to the bottom layout guide)

  • change the constraint priority of the top constraint to 250 (low)

This is to let the whole content view slide upwards when the keyboard appears. The priority must be lower than any other constraint priority in the subviews, including content hugging priorities / content compression resistance priorities.

  • Make sure that your Autolayout has enough constraints to determine how the contentView should slide up.

You may have to add a "greater than equal" constraint for this:

And here you go!


Dicha extensión simple UIViewController se puede usar

//MARK: - Observers extension UIViewController { func addObserverForNotification(notificationName: String, actionBlock: (NSNotification) -> Void) { NSNotificationCenter.defaultCenter().addObserverForName(notificationName, object: nil, queue: NSOperationQueue.mainQueue(), usingBlock: actionBlock) } func removeObserver(observer: AnyObject, notificationName: String) { NSNotificationCenter.defaultCenter().removeObserver(observer, name: notificationName, object: nil) } } //MARK: - Keyboard observers extension UIViewController { typealias KeyboardHeightClosure = (CGFloat) -> () func addKeyboardChangeFrameObserver(willShow willShowClosure: KeyboardHeightClosure?, willHide willHideClosure: KeyboardHeightClosure?) { NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardWillChangeFrameNotification, object: nil, queue: NSOperationQueue.mainQueue(), usingBlock: { [weak self](notification) in if let userInfo = notification.userInfo, let frame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue(), let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Double, let c = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? UInt, let kFrame = self?.view.convertRect(frame, fromView: nil), let kBounds = self?.view.bounds { let animationType = UIViewAnimationOptions(rawValue: c) let kHeight = kFrame.size.height UIView.animateWithDuration(duration, delay: 0, options: animationType, animations: { if CGRectIntersectsRect(kBounds, kFrame) { // keyboard will be shown willShowClosure?(kHeight) } else { // keyboard will be hidden willHideClosure?(kHeight) } }, completion: nil) } else { print("Invalid conditions for UIKeyboardWillChangeFrameNotification") } }) } func removeKeyboardObserver() { removeObserver(self, notificationName: UIKeyboardWillChangeFrameNotification) } }

Ejemplo de uso

override func viewWillDisappear(animated: Bool) { super.viewDidDisappear(animated) removeKeyboardObserver() } override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) addKeyboardChangeFrameObserver(willShow: { [weak self](height) in //Update constraints here self?.view.setNeedsUpdateConstraints() }, willHide: { [weak self](height) in //Reset constraints here self?.view.setNeedsUpdateConstraints() }) }

Solución Swift 4

//MARK: - Observers extension UIViewController { func addObserverForNotification(_ notificationName: Notification.Name, actionBlock: @escaping (Notification) -> Void) { NotificationCenter.default.addObserver(forName: notificationName, object: nil, queue: OperationQueue.main, using: actionBlock) } func removeObserver(_ observer: AnyObject, notificationName: Notification.Name) { NotificationCenter.default.removeObserver(observer, name: notificationName, object: nil) } } //MARK: - Keyboard handling extension UIViewController { typealias KeyboardHeightClosure = (CGFloat) -> () func addKeyboardChangeFrameObserver(willShow willShowClosure: KeyboardHeightClosure?, willHide willHideClosure: KeyboardHeightClosure?) { NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil, queue: OperationQueue.main, using: { [weak self](notification) in if let userInfo = notification.userInfo, let frame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue, let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Double, let c = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? UInt, let kFrame = self?.view.convert(frame, from: nil), let kBounds = self?.view.bounds { let animationType = UIViewAnimationOptions(rawValue: c) let kHeight = kFrame.size.height UIView.animate(withDuration: duration, delay: 0, options: animationType, animations: { if kBounds.intersects(kFrame) { // keyboard will be shown willShowClosure?(kHeight) } else { // keyboard will be hidden willHideClosure?(kHeight) } }, completion: nil) } else { print("Invalid conditions for UIKeyboardWillChangeFrameNotification") } }) } func removeKeyboardObserver() { removeObserver(self, notificationName: NSNotification.Name.UIKeyboardWillChangeFrame) } }


Esta es una versión mejorada de la respuesta de @JosephLord y @ Hlung. Se puede aplicar ya sea que tenga tabbar o no. Y restauraría perfectamente la vista que mueve el teclado a la posición original.

// You have to set this up in storyboard first!. // It''s a vertical spacing constraint between view and bottom of superview. @IBOutlet weak var bottomSpacingConstraint: NSLayoutConstraint! override func viewDidLoad() { super.viewDidLoad() // Receive(Get) Notification NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardNotification:", name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardNotification:", name: UIKeyboardWillHideNotification, object: nil) self.originalConstraint = self.keyboardHeightLayoutConstraint?.constant //for original coordinate. } func keyboardNotification(notification: NSNotification) { let isShowing = notification.name == UIKeyboardWillShowNotification var tabbarHeight: CGFloat = 0 if self.tabBarController? != nil { tabbarHeight = self.tabBarController!.tabBar.frame.height } if let userInfo = notification.userInfo { let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() let duration:NSTimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0 let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber let animationCurveRaw = animationCurveRawNSN?.unsignedLongValue ?? UIViewAnimationOptions.CurveEaseInOut.rawValue let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw) self.keyboardHeightLayoutConstraint?.constant = isShowing ? (endFrame!.size.height - tabbarHeight) : self.originalConstraint! UIView.animateWithDuration(duration, delay: NSTimeInterval(0), options: animationCurve, animations: { self.view.layoutIfNeeded() }, completion: nil) } }


Hay un par de mejoras que deben hacerse en las respuestas existentes.

En primer lugar, UIKeyboardWillChangeFrameNotification es probablemente la mejor notificación ya que maneja cambios que no son solo mostrar / ocultar, sino cambios debidos a cambios en el teclado (lenguaje, uso de teclados de terceros, etc.) y rotaciones también.

En segundo lugar, los parámetros de animación se pueden extraer de la notificación para garantizar que las animaciones estén juntas.

Probablemente haya opciones para limpiar este código un poco más, especialmente si se siente cómodo con desenredar el código del diccionario.

Swift 3.x / 4.x

class MyViewController: UIViewController { // This constraint ties an element at zero points from the bottom layout guide @IBOutlet var keyboardHeightLayoutConstraint: NSLayoutConstraint? override func viewDidLoad() { super.viewDidLoad() // Note that SO highlighting makes the new selector syntax (#selector()) look // like a comment but it isn''t one NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardNotification(notification:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil) } deinit { NotificationCenter.default.removeObserver(self) } @objc func keyboardNotification(notification: NSNotification) { if let userInfo = notification.userInfo { let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue let endFrameY = endFrame.origin.y ?? 0 let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0 let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw) if endFrameY >= UIScreen.main.bounds.size.height { self.keyboardHeightLayoutConstraint?.constant = 0.0 } else { self.keyboardHeightLayoutConstraint?.constant = endFrame?.size.height ?? 0.0 } UIView.animate(withDuration: duration, delay: TimeInterval(0), options: animationCurve, animations: { self.view.layoutIfNeeded() }, completion: nil) } }

Swift 2.x

class MyViewController: UIViewController { // This constraint ties an element at zero points from the bottom layout guide @IBOutlet var keyboardHeightLayoutConstraint: NSLayoutConstraint? override func viewDidLoad() { super.viewDidLoad() // Note that SO highlighting makes the new selector syntax (#selector()) look // like a comment but it isn''t one NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.keyboardNotification(_:)), name: UIKeyboardWillChangeFrameNotification, object: nil) } deinit { NSNotificationCenter.defaultCenter().removeObserver(self) } func keyboardNotification(notification: NSNotification) { if let userInfo = notification.userInfo { let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() let duration:NSTimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0 let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber let animationCurveRaw = animationCurveRawNSN?.unsignedLongValue ?? UIViewAnimationOptions.CurveEaseInOut.rawValue let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw) if endFrame?.origin.y >= UIScreen.mainScreen().bounds.size.height { self.keyboardHeightLayoutConstraint?.constant = 0.0 } else { self.keyboardHeightLayoutConstraint?.constant = endFrame?.size.height ?? 0.0 } UIView.animateWithDuration(duration, delay: NSTimeInterval(0), options: animationCurve, animations: { self.view.layoutIfNeeded() }, completion: nil) } }

(Editado para tener en cuenta la animación de teclado fuera de pantalla en lugar de disminuir, según el asombroso comentario de @Gabox a continuación)


La forma más sencilla que no requiere ningún código:

  1. Descargue KeyboardLayoutConstraint y agregue (arrastre y suelte) el archivo en su proyecto, si ya no está usando el marco de animación de Spring.
  2. En su guión gráfico, cree una restricción inferior para el objeto / vista / campo de texto, seleccione la restricción (haga doble clic en ella) y en el Inspector de identidad, cambie su clase de NSLayoutConstraint a KeyboardLayoutConstraint.
  3. ¡Hecho!

El objeto se moverá automáticamente hacia arriba con el teclado, en sincronización.


Me encanta el código limpio de Swift. Así que aquí está el código más estricto que pude encontrar para mover una vista de texto hacia arriba / abajo con el teclado. Actualmente está trabajando en una aplicación de producción iOS8 / 9 Swift 2.

ACTUALIZACIÓN (marzo de 2016): Acabo de reforzar mi código anterior tanto como sea posible. Además, hay un montón de respuestas populares que codifican la altura del teclado y los parámetros de animación. No hay necesidad de eso, sin mencionar que los números en estas respuestas no siempre se alinean con los valores reales que estoy viendo en mis 6s + iOS9 (altura del teclado de 226, duración de 0.25 y curva de animación de 7). En cualquier caso, casi no hay código extra para obtener esos valores directamente del sistema. Vea abajo.

override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: "animateWithKeyboard:", name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: "animateWithKeyboard:", name: UIKeyboardWillHideNotification, object: nil) } func animateWithKeyboard(notification: NSNotification) { // Based on both Apple''s docs and personal experience, // I assume userInfo and its documented keys are available. // If you''d like, you can remove the forced unwrapping and add your own default values. let userInfo = notification.userInfo! let keyboardHeight = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().height let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as! Double let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] as! UInt let moveUp = (notification.name == UIKeyboardWillShowNotification) // baseContraint is your Auto Layout constraint that pins the // text view to the bottom of the superview. baseConstraint.constant = moveUp ? -keyboardHeight : 0 let options = UIViewAnimationOptions(rawValue: curve << 16) UIView.animateWithDuration(duration, delay: 0, options: options, animations: { self.view.layoutIfNeeded() }, completion: nil ) }

NOTA: Este código cubre la mayoría del comentario / caso general. Sin embargo, es posible que se necesite más código para manejar diferentes orientaciones y / o teclados personalizados. Aquí hay un artículo en profundidad sobre cómo trabajar con el teclado de iOS. Si necesita manejar cada escenario, esto puede ayudar.


Otra solución que no depende de autolayout, restricciones o salidas. Lo que necesita es su campo (s) en una vista de desplazamiento.

override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: "makeSpaceForKeyboard:", name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: "makeSpaceForKeyboard:", name: UIKeyboardWillHideNotification, object: nil) } func makeSpaceForKeyboard(notification: NSNotification) { let info = notification.userInfo! let keyboardHeight:CGFloat = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().size.height let duration:Double = info[UIKeyboardAnimationDurationUserInfoKey] as! Double if notification.name == UIKeyboardWillShowNotification { UIView.animateWithDuration(duration, animations: { () -> Void in var frame = self.view.frame frame.size.height = frame.size.height - keyboardHeight self.view.frame = frame }) } else { UIView.animateWithDuration(duration, animations: { () -> Void in var frame = self.view.frame frame.size.height = frame.size.height + keyboardHeight self.view.frame = frame }) } }


Para mover su vista mientras edita el campo de texto, intente esto, lo he aplicado, funciona bien

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

Recibí esta respuesta de esta fuente. UITextField se mueve hacia arriba cuando aparece el teclado en Swift


Si está utilizando Diseño automático, supongo que ha establecido la restricción Espacio inferior a Superview . Si ese es el caso, simplemente tiene que actualizar el valor de la restricción. Así es como lo haces con un poco de animación.

func keyboardWasShown(notification: NSNotification) { let info = notification.userInfo! let keyboardFrame: CGRect = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue() UIView.animateWithDuration(0.1, animations: { () -> Void in self.bottomConstraint.constant = keyboardFrame.size.height + 20 }) }

El código fijo 20 se agrega solo para mostrar el campo de texto sobre el teclado solo un poco. De lo contrario, el margen superior del teclado y el margen inferior del campo de texto se tocarían.

Cuando se cierra el teclado, restablezca el valor de la restricción a su valor original.


Una solución simple es mover la vista hacia arriba con una constante de altura del teclado.

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 // Move view 150 points upward } func keyboardWillHide(sender: NSNotification) { self.view.frame.origin.y = 0 // Move view to original position }

Swift 3

NotificationCenter.default.addObserver(self, selector: #selector(RegisterViewController.keyboardWillShow(sender:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(RegisterViewController.keyboardWillHide(sender:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)


Editar : Recomiendo una solución más fácil y más limpia. Simplemente cambie la clase de restricción de espaciado inferior a KeyboardLayoutConstraint . Se expandirá automáticamente a la altura del teclado.

Esta es una versión mejorada de la respuesta de @JosephLord.

Como se probó en iOS 8.3 iPad Simulator, Portrait. Xcode6.3 beta4, encontré que su respuesta no funciona cuando el teclado está escondido porque UIKeyboardFrameEndUserInfoKey es "NSRect: {{0, 1024}, {768, 264}}"; . La altura nunca es 0 .

Esto vuelve a usar el UIKeyboardWillShowNotification y el UIKeyboardWillHideNotification tradicionales para saber mejor cuándo se esconde el teclado en lugar de depender del alto del marco final. UIKeyboardWillShowNotification también se envía cuando se cambia el marco del teclado, por lo que debe cubrir todos los casos de uso.

// You have to set this up in storyboard first!. // It''s a vertical spacing constraint between view and bottom of superview. @IBOutlet weak var bottomSpacingConstraint: NSLayoutConstraint! override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardNotification:"), name:UIKeyboardWillShowNotification, object: nil); NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardNotification:"), name:UIKeyboardWillHideNotification, object: nil); } deinit { NSNotificationCenter.defaultCenter().removeObserver(self) } func keyboardNotification(notification: NSNotification) { let isShowing = notification.name == UIKeyboardWillShowNotification if let userInfo = notification.userInfo { let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() let endFrameHeight = endFrame?.size.height ?? 0.0 let duration:NSTimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0 let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber let animationCurveRaw = animationCurveRawNSN?.unsignedLongValue ?? UIViewAnimationOptions.CurveEaseInOut.rawValue let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw) self.bottomSpacingConstraint?.constant = isShowing ? endFrameHeight : 0.0 UIView.animateWithDuration(duration, delay: NSTimeInterval(0), options: animationCurve, animations: { self.view.layoutIfNeeded() }, completion: nil) } }


En Swift 4.0 -

func textFieldDidBeginEditing(_ textField: UITextField) { animateViewMoving(up: true, moveValue: 100) } func textFieldDidEndEditing(_ textField: UITextField) { animateViewMoving(up: false, moveValue: 100) } func animateViewMoving (up:Bool, moveValue :CGFloat){ let movementDuration:TimeInterval = 0.3 let movement:CGFloat = ( up ? -moveValue : moveValue) UIView.beginAnimations( "animateView", context: nil) UIView.setAnimationBeginsFromCurrentState(true) UIView.setAnimationDuration(movementDuration ) self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement) UIView.commitAnimations() }


I have done in following manner :

class SignInController: UIViewController , UITextFieldDelegate { @IBOutlet weak var scrollView: UIScrollView! // outlet declartion @IBOutlet weak var signInTextView: UITextField! var kbHeight: CGFloat! /** * * @method viewDidLoad * */ override func viewDidLoad() { super.viewDidLoad() self.signInTextView.delegate = self }// end viewDidLoad /** * * @method viewWillAppear * */ override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil) }// end viewWillAppear /** * * @method viewDidAppear * */ override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) }// end viewDidAppear /** * * @method viewWillDisappear * */ override func viewWillDisappear(animated: Bool) { super.viewWillDisappear(animated) NSNotificationCenter.defaultCenter().removeObserver(self) } /** * * @method textFieldShouldReturn * retun the keyboard value * */ // MARK - func textFieldShouldReturn(textField: UITextField) -> Bool { signInTextView.resignFirstResponder() return true; }// end textFieldShouldReturn // MARK - keyboardWillShow func keyboardWillShow(notification: NSNotification) { if let userInfo = notification.userInfo { if let keyboardSize = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { kbHeight = keyboardSize.height self.animateTextField(true) } } }// end keyboardWillShow // MARK - keyboardWillHide func keyboardWillHide(notification: NSNotification) { self.animateTextField(false) }// end keyboardWillHide // MARK - animateTextField func animateTextField(up: Bool) { var movement = (up ? -kbHeight : kbHeight) UIView.animateWithDuration(0.3, animations: { self.view.frame = CGRectOffset(self.view.frame, 0, movement) }) }// end animateTextField /** * * @method didReceiveMemoryWarning * */ override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. }// end didReceiveMemoryWarning }// end SignInController


I modified @Simpa solution a little bit.........

override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("makeSpaceForKeyboard:"), name:UIKeyboardWillShowNotification, object: nil); NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("makeSpaceForKeyboard:"), name:UIKeyboardWillHideNotification, object: nil); } deinit{ NSNotificationCenter.defaultCenter().removeObserver(self) } var keyboardIsVisible = false override func makeSpaceForKeyboard(notification: NSNotification) { let info = notification.userInfo! let keyboardHeight:CGFloat = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().size.height let duration:Double = info[UIKeyboardAnimationDurationUserInfoKey] as! Double if notification.name == UIKeyboardWillShowNotification && keyboardIsVisible == false{ keyboardIsVisible = true UIView.animateWithDuration(duration, animations: { () -> Void in var frame = self.view.frame frame.size.height = frame.size.height - keyboardHeight self.view.frame = frame }) } else if keyboardIsVisible == true && notification.name == UIKeyboardWillShowNotification{ }else { keyboardIsVisible = false UIView.animateWithDuration(duration, animations: { () -> Void in var frame = self.view.frame frame.size.height = frame.size.height + keyboardHeight self.view.frame = frame }) } }



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. All the best

None of them worked for and I ended up using content insets to move my view up when the keyboard appears.

Note: I was using a UITableView

Referenced solution @ keyboard-content-offset which was entirely written in objective C, the below solution is clean Swift.

Add the notification observer @ viewDidLoad()

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(yourClass.keyboardWillBeShown), name:UIKeyboardWillShowNotification, object: nil); NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(yourClass.keyboardWillBeHidden), name:UIKeyboardWillHideNotification, object: nil);

To get the keyboard size, we first get the userInfo dictionary from the notification object, which stores any additional objects that our receiver might use.

From that dictionary we can get the CGRect object describing the keyboard''s frame by using the key UIKeyboardFrameBeginUserInfoKey.

Apply the content inset for the table view @ keyboardWillBeShown method,

func keyboardWillBeShown(sender: NSNotification) { // Move the table view if let keyboardSize = (sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() { let contentInsets = UIEdgeInsetsMake(0.0, 0.0, (keyboardSize.height), 0.0); yourTableView.contentInset = contentInsets; yourTableView.scrollIndicatorInsets = contentInsets; } }

Restore the view @ keyboardWillBeHidden method

func keyboardWillBeHidden(sender: NSNotification) { // Moving back the table view back to the default position yourTableView.contentInset = UIEdgeInsetsZero; yourTableView.scrollIndicatorInsets = UIEdgeInsetsZero; }

If you want to keep the device orientation also into consideration, use conditional statements to tailor the code to your needs.

// Portrait UIEdgeInsetsMake(0.0, 0.0, (keyboardSize.height), 0.0); // Landscape UIEdgeInsetsMake(0.0, 0.0, (keyboardSize.width), 0.0);


The Swift 4 solution I use, takes in keyboard size. Replace serverStatusStackView with whatever view you care about, eg: self.view :

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


The following is a simple solution, whereby the text field has a constraint tying it to the bottom layout guide. It simply adds the keyboard height to the constraint''s constant.

// This constraint ties the text field to the bottom layout guide @IBOutlet var textFieldToBottomLayoutGuideConstraint: NSLayoutConstraint! override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name:UIKeyboardWillShowNotification, object: nil); NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name:UIKeyboardWillHideNotification, object: nil); } func keyboardWillShow(sender: NSNotification) { if let keyboardSize = (sender.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { self.textFieldToBottomLayoutGuideConstraint?.constant += keyboardSize.height } } func keyboardWillHide(sender: NSNotification) { if let keyboardSize = (sender.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { self.textFieldToBottomLayoutGuideConstraint?.constant -= keyboardSize.height } }


Well, I think i might be too late but i found another simple version of Saqib''s answer. I''m using Autolayout with constraints. I have a small view inside of another main view with username and password fields. Instead of changing the y coordinate of the view i''m saving the original constraint value in a variable and changing the constraint''s constant to some value and again after the keyboard dismisses, i''m setting up the constraint to original one. This way it avoids the problem Saqib''s answer has, (The view keeps on moving up and does not stop). Below is my code...

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); self.originalConstraint = self.centerYConstraint.constant } func keyboardWillShow(sender: NSNotification) { self.centerYConstraint.constant += 30 } func keyboardWillHide(sender: NSNotification) { self.centerYConstraint.constant = self.originalConstraint }


You can use this library and just one line of code in appDidFinishedLaunching and u are done..

func application(application: UIApplication,didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { IQKeyboardManager.sharedManager().enable = true return true }

IQKeyboardManager - adjust view whenever keyboard appear link - https://github.com/hackiftekhar/IQKeyboardManager


i am working with swift 4 and i am solved this issue without use any extra bottom constraint look my code is here.its really working on my case

1) Add Notification Observer in did load

override func viewDidLoad() { super.viewDidLoad() setupManager() // Do any additional setup after loading the view. 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) }

2) Remove Notification Observer like

deinit { NotificationCenter.default.removeObserver(self) }

3) Add keyboard show/ hide methods like

@objc func keyboardWillShow(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { UIView.animate(withDuration: 0.1, animations: { () -> Void in self.view.frame.origin.y -= keyboardSize.height self.view.layoutIfNeeded() }) } } @objc func keyboardWillHide(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { UIView.animate(withDuration: 0.1, animations: { () -> Void in self.view.frame.origin.y += keyboardSize.height self.view.layoutIfNeeded() }) } }

4) Add textfeild delegate and add touchesBegan methods .usefull for hide the keyboard when touch outside the textfeild on screen

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { view.endEditing(true) }



Si no te importa usar la biblioteca Objective-C en tu proyecto Swift, quizás puedas usar esta helper . Viene con un ejemplo para el uso de Swift también.


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 }


override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. 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:Notification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0) } } func keyboardWillHide(_ notification:Notification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0) } }


struct MoveKeyboard { static let KEYBOARD_ANIMATION_DURATION : CGFloat = 0.3 static let MINIMUM_SCROLL_FRACTION : CGFloat = 0.2; static let MAXIMUM_SCROLL_FRACTION : CGFloat = 0.8; static let PORTRAIT_KEYBOARD_HEIGHT : CGFloat = 216; static let LANDSCAPE_KEYBOARD_HEIGHT : CGFloat = 162; } func textFieldDidBeginEditing(textField: UITextField) { let textFieldRect : CGRect = self.view.window!.convertRect(textField.bounds, fromView: textField) let viewRect : CGRect = self.view.window!.convertRect(self.view.bounds, fromView: self.view) let midline : CGFloat = textFieldRect.origin.y + 0.5 * textFieldRect.size.height let numerator : CGFloat = midline - viewRect.origin.y - MoveKeyboard.MINIMUM_SCROLL_FRACTION * viewRect.size.height let denominator : CGFloat = (MoveKeyboard.MAXIMUM_SCROLL_FRACTION - MoveKeyboard.MINIMUM_SCROLL_FRACTION) * viewRect.size.height var heightFraction : CGFloat = numerator / denominator if heightFraction < 0.0 { heightFraction = 0.0 } else if heightFraction > 1.0 { heightFraction = 1.0 } let orientation : UIInterfaceOrientation = UIApplication.sharedApplication().statusBarOrientation if (orientation == UIInterfaceOrientation.Portrait || orientation == UIInterfaceOrientation.PortraitUpsideDown) { animateDistance = floor(MoveKeyboard.PORTRAIT_KEYBOARD_HEIGHT * heightFraction) } else { animateDistance = floor(MoveKeyboard.LANDSCAPE_KEYBOARD_HEIGHT * heightFraction) } var viewFrame : CGRect = self.view.frame viewFrame.origin.y -= animateDistance UIView.beginAnimations(nil, context: nil) UIView.setAnimationBeginsFromCurrentState(true) UIView.setAnimationDuration(NSTimeInterval(MoveKeyboard.KEYBOARD_ANIMATION_DURATION)) self.view.frame = viewFrame UIView.commitAnimations() } func textFieldDidEndEditing(textField: UITextField) { var viewFrame : CGRect = self.view.frame viewFrame.origin.y += animateDistance UIView.beginAnimations(nil, context: nil) UIView.setAnimationBeginsFromCurrentState(true) UIView.setAnimationDuration(NSTimeInterval(MoveKeyboard.KEYBOARD_ANIMATION_DURATION)) self.view.frame = viewFrame UIView.commitAnimations() }

Y, por último, ya que estamos utilizando métodos delegados

func textFieldShouldReturn(textField: UITextField) -> Bool { textField.resignFirstResponder() return true }

refactorizado de usar objetivo-c http://www.cocoawithlove.com/2008/10/sliding-uitextfields-around-to-avoid.html