He intentado agregar código para mover mi vista hacia arriba cuando aparece el teclado, sin embargo, tengo problemas al intentar traducir los ejemplos de Objective-C a Swift. He hecho algunos progresos, pero estoy estancado en una línea en particular.
Estos son los dos tutoriales / preguntas que he estado siguiendo:
Cómo mover el contenido de UIViewController hacia arriba a medida que aparece el teclado usando Swift http://www.ioscreator.com/tutorials/move-view-when-keyboard-appears
Aquí está el código que tengo actualmente:
override func viewWillAppear(animated: Bool) {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func keyboardWillShow(notification: NSNotification) {
var keyboardSize = notification.userInfo(valueForKey(UIKeyboardFrameBeginUserInfoKey))
UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
let frame = self.budgetEntryView.frame
frame.origin.y = frame.origin.y - keyboardSize
self.budgetEntryView.frame = frame
}
func keyboardWillHide(notification: NSNotification) {
//
}
Por el momento, recibo un error en esta línea:
var keyboardSize = notification.userInfo(valueForKey(UIKeyboardFrameBeginUserInfoKey))
Si alguien pudiera decirme cuál debería ser esta línea de código, me las arreglaría para averiguar el resto yo mismo.
fuente
Para incluso menos código, considere mirar ESTO
Fue muy útil para mí. Solo tiene que incluir la restricción de vista en el controlador de vista y usar los dos observadores que agregó. Luego solo use los siguientes métodos (se supone que aquí mueve un tableView)
func keyboardWillShow(sender: NSNotification) { if let userInfo = sender.userInfo { if let keyboardHeight = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue().size.height { tableViewBottomConstraint.constant = keyboardHeight UIView.animateWithDuration(0.25, animations: { () -> Void in self.view.layoutIfNeeded() }) } } }
y
func keyboardWillHide(sender: NSNotification) { if let userInfo = sender.userInfo { if let keyboardHeight = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue().size.height { tableViewBottomConstraint.constant = 0.0 UIView.animateWithDuration(0.25, animations: { () -> Void in self.view.layoutIfNeeded() }) } } }
fuente
Si está utilizando un guión gráfico, en lugar de manipular la vista en sí, puede aprovechar el diseño automático.
(Esta es una versión limpia de la respuesta de Nicholas)
Configure el centro de notificaciones para que le notifique la aparición y desaparición del teclado:
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) }
Y asegúrese de eliminar los observadores cuando ya no los necesite:
override func viewWillDisappear(animated: Bool) { super.viewWillDisappear(animated) NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: self.view.window) NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: self.view.window) }
Dentro del guión gráfico, establezca la restricción inferior. Cree una salida de esa restricción:
y establece la propiedad constante de la restricción cuando el teclado se muestra u oculta:
func keyboardWillShow(notification: NSNotification) { guard let keyboardHeight = (notification.userInfo! as NSDictionary).objectForKey(UIKeyboardFrameBeginUserInfoKey)?.CGRectValue.size.height else { return } nameOfOutlet.constant = keyboardHeight view.layoutIfNeeded() } func keyboardWillHide(notification: NSNotification) { nameOfOutlet.constant = 0.0 view.layoutIfNeeded() }
Ahora, siempre que el teclado aparezca o desaparezca, el diseño automático se encargará de todo.
fuente
Swift 2
func keyboardWasShown(notification:NSNotification) { guard let info:[NSObject:AnyObject] = notification.userInfo, let keyboardSize:CGSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size else { return } let insets:UIEdgeInsets = UIEdgeInsetsMake(self.scrollView.contentInset.top, 0.0, keyboardSize.height, 0.0) self.scrollView.contentInset = insets self.scrollView.scrollIndicatorInsets = insets }
Swift 3
func keyboardWasShown(notification:NSNotification) { guard let info:[AnyHashable:Any] = notification.userInfo, let keyboardSize:CGSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size else { return } let insets:UIEdgeInsets = UIEdgeInsets(top: self.scrollView.contentInset.top, left: 0.0, bottom: keyboardSize.height, right: 0.0) self.scrollView.contentInset = insets self.scrollView.scrollIndicatorInsets = insets }
fuente
Esto me ayudó: https://developer.apple.com/library/ios/samplecode/UICatalog/Listings/Swift_UICatalog_TextViewController_swift.html
let userInfo = notification.userInfo! let animationDuration: NSTimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as NSNumber).doubleValue let keyboardScreenBeginFrame = (userInfo[UIKeyboardFrameBeginUserInfoKey] as NSValue).CGRectValue() let keyboardScreenEndFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as NSValue).CGRectValue()
fuente
Puedes usar esta línea para tu línea
var keyboardSize:CGSize = userInfo.objectForKey(UIKeyboardFrameBeginUserInfoKey)!.CGRectValue().size
fuente
Swift 3: ACTUALIZAR
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) 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) } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: self.view.window) NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: self.view.window) }
fuente
Swift - Altura del teclado desde el tecladoWillShowNotification
Puede aumentar o reducir una restricción, o cualquier otro valor, al tamaño del teclado utilizando los datos del teclado Will / did Mostrar / ocultar notificaciones.
Con una restricción de diseño
Este código mínimo se registra para la notificación de que el teclado mostrará y actualiza una restricción en función de su tamaño.
@IBOutlet weak var keyboardConstraint: NSLayoutConstraint! let keyboardConstraintMargin:CGFloat = 20 override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: nil) { (notification) in if let keyboardSize = notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? CGRect { self.keyboardConstraint.constant = keyboardSize.height + self.keyboardConstraintMargin } } NotificationCenter.default.addObserver(forName: UIResponder.keyboardDidHideNotification, object: nil, queue: nil) { (notification) in self.keyboardConstraint.constant = self.keyboardConstraintMargin } }
Con un ScrollView
De la misma manera, esto actualiza la inserción de contenido de una vista de desplazamiento según el tamaño del teclado.
@IBOutlet weak var scrollView: UIScrollView! override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: nil) { (notification) in if let keyboardSize = notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? CGRect { let insets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0) self.scrollView.contentInset = insets self.scrollView.scrollIndicatorInsets = insets } } NotificationCenter.default.addObserver(forName: UIResponder.keyboardDidHideNotification, object: nil, queue: nil) { (notification) in let insets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) self.scrollView.contentInset = insets self.scrollView.scrollIndicatorInsets = insets } }
fuente
Detalles
Solución
import UIKit protocol KeyboardNotificationsDelegate: class { func keyboardWillShow(notification: NSNotification) func keyboardWillHide(notification: NSNotification) func keyboardDidShow(notification: NSNotification) func keyboardDidHide(notification: NSNotification) } extension KeyboardNotificationsDelegate { func keyboardWillShow(notification: NSNotification) {} func keyboardWillHide(notification: NSNotification) {} func keyboardDidShow(notification: NSNotification) {} func keyboardDidHide(notification: NSNotification) {} } class KeyboardNotifications { fileprivate var _isEnabled: Bool fileprivate var notifications: [KeyboardNotificationsType] fileprivate weak var delegate: KeyboardNotificationsDelegate? init(notifications: [KeyboardNotificationsType], delegate: KeyboardNotificationsDelegate) { _isEnabled = false self.notifications = notifications self.delegate = delegate } deinit { if isEnabled { isEnabled = false } } } // MARK: - enums extension KeyboardNotifications { enum KeyboardNotificationsType { case willShow, willHide, didShow, didHide var selector: Selector { switch self { case .willShow: return #selector(keyboardWillShow(notification:)) case .willHide: return #selector(keyboardWillHide(notification:)) case .didShow: return #selector(keyboardDidShow(notification:)) case .didHide: return #selector(keyboardDidHide(notification:)) } } var notificationName: NSNotification.Name { switch self { case .willShow: return UIResponder.keyboardWillShowNotification case .willHide: return UIResponder.keyboardWillHideNotification case .didShow: return UIResponder.keyboardDidShowNotification case .didHide: return UIResponder.keyboardDidHideNotification } } } } // MARK: - isEnabled extension KeyboardNotifications { private func addObserver(type: KeyboardNotificationsType) { NotificationCenter.default.addObserver(self, selector: type.selector, name: type.notificationName, object: nil) } var isEnabled: Bool { set { if newValue { for notificaton in notifications { addObserver(type: notificaton) } } else { NotificationCenter.default.removeObserver(self) } _isEnabled = newValue } get { return _isEnabled } } } // MARK: - Notification functions extension KeyboardNotifications { @objc func keyboardWillShow(notification: NSNotification) { delegate?.keyboardWillShow(notification: notification) } @objc func keyboardWillHide(notification: NSNotification) { delegate?.keyboardWillHide(notification: notification) } @objc func keyboardDidShow(notification: NSNotification) { delegate?.keyboardDidShow(notification: notification) } @objc func keyboardDidHide(notification: NSNotification) { delegate?.keyboardDidHide(notification: notification) } }
Uso
class ViewController: UIViewController { private lazy var keyboardNotifications: KeyboardNotifications! = { return KeyboardNotifications(notifications: [.willShow, .willHide, .didShow, .didHide], delegate: self) }() override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) keyboardNotifications.isEnabled = true } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) keyboardNotifications.isEnabled = false } } extension ViewController: KeyboardNotificationsDelegate { // If you don't need this func you can remove it func keyboardWillShow(notification: NSNotification) { print("keyboardWillShow") guard let userInfo = notification.userInfo as? [String: NSObject], let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } print("keyboardFrame: \(keyboardFrame)") } // If you don't need this func you can remove it func keyboardWillHide(notification: NSNotification) { print("keyboardWillHide") } // If you don't need this func you can remove it func keyboardDidShow(notification: NSNotification) { print("keyboardDidShow") } // If you don't need this func you can remove it func keyboardDidHide(notification: NSNotification) { print("keyboardDidHide") } }
Muestra completa
import UIKit class ViewController: UIViewController { private lazy var keyboardNotifications: KeyboardNotifications! = { return KeyboardNotifications(notifications: [.willShow, .willHide, .didShow, .didHide], delegate: self) }() override func viewDidLoad() { super.viewDidLoad() let textField = UITextField(frame: CGRect(x: 40, y: 40, width: 200, height: 30)) textField.borderStyle = .roundedRect view.addSubview(textField) let gesture = UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))) view.addGestureRecognizer(gesture) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) keyboardNotifications.isEnabled = true } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) keyboardNotifications.isEnabled = false } } extension ViewController: KeyboardNotificationsDelegate { // If you don't need this func you can remove it func keyboardWillShow(notification: NSNotification) { print("keyboardWillShow") guard let userInfo = notification.userInfo as? [String: NSObject], let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } print("keyboardFrame: \(keyboardFrame)") } // If you don't need this func you can remove it func keyboardWillHide(notification: NSNotification) { print("keyboardWillHide") } // If you don't need this func you can remove it func keyboardDidShow(notification: NSNotification) { print("keyboardDidShow") } // If you don't need this func you can remove it func keyboardDidHide(notification: NSNotification) { print("keyboardDidHide") } }
Resultado
Iniciar sesión
fuente
Swift 3.0
Aquí hay un ejemplo de cómo recuperar el tamaño del teclado y usarlo para animar una vista hacia arriba. En mi caso, estoy moviendo una UIView que contiene mis UITextFields hacia arriba cuando un usuario comienza a escribir para que puedan completar un formulario y seguir viendo el botón de envío en la parte inferior.
Agregué una salida a la restricción de espacio inferior de la vista que quería animar y la nombré llamada
myViewsBottomSpaceConstraint
:@IBOutlet weak var myViewsBottomSpaceConstraint: NSLayoutConstraint!
Luego agregué el siguiente código a mi clase rápida:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) 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) } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) 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 userInfo = notification.userInfo as! [String: NSObject] as NSDictionary let keyboardFrame = userInfo.value(forKey: UIKeyboardFrameEndUserInfoKey) as! CGRect let keyboardHeight = keyboardFrame.height myViewsBottomSpaceConstraint.constant = keyboardHeight view.layoutIfNeeded() } func keyboardWillHide(notification: NSNotification) { myViewsBottomSpaceConstraint.constant = 0.0 view.layoutIfNeeded() }
fuente
Para xamarin, puede usar c # 6
private void KeyboardWillChangeFrame(NSNotification notification) { var keyboardSize = notification.UserInfo.ValueForKey(UIKeyboard.FrameEndUserInfoKey) as NSValue; if (keyboardSize != null) { var rect= keyboardSize.CGRectValue; //do your stuff here } }
c # 7
private void KeyboardWillChangeFrame(NSNotification notification) { if (!(notification.UserInfo.ValueForKey(UIKeyboard.FrameEndUserInfoKey) is NSValue keyboardSize)) return; var rect= keyboardSize.CGRectValue; }
fuente
en Swift 4.2 puede usar UIResponder.keyboardFrameEndUserInfoKey
guard let userInfo = notification.userInfo , let keyboardFrame:CGRect = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }```
fuente