Estaba usando este código para determinar cuál es el tamaño del teclado:
- (void)keyboardWillChange:(NSNotification *)notification {
NSDictionary* keyboardInfo = [notification userInfo];
NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];
}
Estoy ejecutando esto en el simulador.
El problema es que desde iOS 8 esto no dará el valor correcto, si las sugerencias del teclado están arriba o si las presiono hacia abajo, obtengo valores diferentes (no correctos).
¿Cómo puedo obtener el tamaño exacto del teclado, incluidas las sugerencias de teclado?
ios
objective-c
cocoa-touch
keyboard
ios8
Eli Braginskiy
fuente
fuente
keyboardFrameBeginRect
a coordenadas locales.Respuestas:
Utilizar
NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameEndUserInfoKey];
fuente
Con la introducción de teclados personalizados en iOS, este problema se vuelve un poco más complejo.
En resumen, la UIKeyboardWillShowNotification puede ser llamada varias veces por implementaciones de teclado personalizadas:
Para manejar estos escenarios correctamente en una línea de código, necesita:
Registre observadores en las notificaciones UIKeyboardWillShowNotification y UIKeyboardWillHideNotification :
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
Cree una variable global para rastrear la altura actual del teclado:
CGFloat _currentKeyboardHeight = 0.0f;
Implemente keyboardWillShow para reaccionar al cambio actual en la altura del teclado:
- (void)keyboardWillShow:(NSNotification*)notification { NSDictionary *info = [notification userInfo]; CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size; CGFloat deltaHeight = kbSize.height - _currentKeyboardHeight; // Write code to adjust views accordingly using deltaHeight _currentKeyboardHeight = kbSize.height; }
NOTA: Es posible que desee animar la compensación de vistas. El diccionario de información contiene un valor introducido por UIKeyboardAnimationDurationUserInfoKey . Este valor puede usarse para animar sus cambios a la misma velocidad que el teclado que se muestra.
Implemente keyboardWillOcultar al reinicio _currentKeyboardHeight y reaccionar cuando se descarte el teclado:
- (void)keyboardWillHide:(NSNotification*)notification { NSDictionary *info = [notification userInfo]; CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size; // Write code to adjust views accordingly using kbSize.height _currentKeyboardHeight = 0.0f; }
fuente
KEYBOARD BEGIN RECT: (0.0, 375.0, 667.0, 162.0) ... KEYBOARD END RECT: (0.0, 213.0, 667.0, 162.0)
También tuve este problema, hasta que me encontré con este StackOverflow artículo de :
Convertir UIKeyboardFrameEndUserInfoKey
Esto le muestra cómo usar la
convertRect
función para convertir el tamaño del teclado en algo utilizable, pero en la orientación de la pantalla.NSDictionary* d = [notification userInfo]; CGRect r = [d[UIKeyboardFrameEndUserInfoKey] CGRectValue]; r = [myView convertRect:r fromView:nil];
Anteriormente, tenía una aplicación para iPad que usaba
UIKeyboardFrameEndUserInfoKey
pero no usabaconvertRect
, y funcionaba bien.Pero con iOS 8, ya no funcionaba correctamente. De repente, informaría que mi teclado, que se ejecuta en un iPad en modo horizontal, tenía 1024 píxeles de alto .
Así que ahora, con iOS 8, es fundamental que utilice esta
convertRect
función.fuente
Similar a la solución de dgangsta escrita en Swift 2.0:
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) { guard let kbSizeValue = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return } guard let kbDurationNumber = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber else { return } animateToKeyboardHeight(kbSizeValue.CGRectValue().height, duration: kbDurationNumber.doubleValue) } func keyboardWillHide(notification: NSNotification) { guard let kbDurationNumber = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber else { return } animateToKeyboardHeight(0, duration: kbDurationNumber.doubleValue) } func animateToKeyboardHeight(kbHeight: CGFloat, duration: Double) { // your custom code here }
fuente
Hago
extension
paraUIViewController
extension UIViewController { func keyboardWillChangeFrameNotification(notification: NSNotification, scrollBottomConstant: NSLayoutConstraint) { let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber let curve = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber let keyboardBeginFrame = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as! NSValue).CGRectValue() let keyboardEndFrame = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue() let screenHeight = UIScreen.mainScreen().bounds.height let isBeginOrEnd = keyboardBeginFrame.origin.y == screenHeight || keyboardEndFrame.origin.y == screenHeight let heightOffset = keyboardBeginFrame.origin.y - keyboardEndFrame.origin.y - (isBeginOrEnd ? bottomLayoutGuide.length : 0) UIView.animateWithDuration(duration.doubleValue, delay: 0, options: UIViewAnimationOptions(rawValue: UInt(curve.integerValue << 16)), animations: { () in scrollBottomConstant.constant = scrollBottomConstant.constant + heightOffset self.view.layoutIfNeeded() }, completion: nil ) } }
Puedes usar así:
override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillChangeFrameNotification:", name: UIKeyboardWillChangeFrameNotification, object: nil) } ... deinit { NSNotificationCenter.defaultCenter().removeObserver(self) } func keyboardWillChangeFrameNotification(notification: NSNotification) { self.keyboardWillChangeFrameNotification(notification, scrollBottomConstant: inputContainerBottom) // Write more to here if you want. }
fuente
inputContainerBottom
?Hay ocasiones en las que los desarrolladores necesitan saber la altura del teclado antes de que se muestre, lo que les permite pre-diseñar la interfaz de forma adecuada.
Si ese es el caso, aquí hay una especificación inclusiva:
Esto incluye la barra de tipo rápido en la parte superior, ya que está activada de forma predeterminada en todas las versiones actuales de iOS.
Aquí está la configuración de notificación Swift 3 que usé para probar esto, si alguien lo necesita:
override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: .UIKeyboardWillShow, object: nil) } func keyboardWillShow(notification: NSNotification) { guard let keyboardSize = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return } print("\(keyboardSize)") }
fuente
Solo una cuerda para veloz:
let keyboardSize = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().size
UIKeyboardFrameEndUserInfoKey
siempre se almacenaNSValue
, por lo que no es necesario comprobarlo.fuente
Noté un problema al cambiar entre el teclado predeterminado y un personalizado (
UIPickerView
): el teclado personalizado mostraría una altura de 253 en lugar de 162, después de cambiar desde el teclado predeterminado.Lo que funcionó en este caso fue la configuración
autocorrectionType = UITextAutocorrectionTypeNo;
del campo de entrada con el teclado personalizado.El problema solo ocurrió en iOS 8 (probado solo en el simulador). No ocurre en iOS 9 (simulador o dispositivo).
fuente
En Swift, no en una sola línea ...
self.keyboardDidShowObserver = NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardDidShowNotification, object: nil, queue: NSOperationQueue.mainQueue(), usingBlock: { (notification) in if let userInfo = notification.userInfo, let keyboardFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue { let keyboardRect = keyboardFrameValue.CGRectValue() // keyboardRect.height gives the height of the keyboard // your additional code here... } })
fuente
[notificationCenter addObserverForName:UIKeyboardWillChangeFrameNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification * _Nonnull note) { float keyboardHeight = [[note.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height; }];
fuente