iOS 11: la altura del teclado devuelve 0 en la notificación del teclado

84

He estado usando las notificaciones del teclado sin ningún problema y obteniendo la altura exacta del teclado.

- (void)keyboardDidShow:(NSNotification *) notification{
    CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    NSLog(@"%f",keyboardSize.height);}

pero con iOS 11 el tamaño del teclado es 0 cuando se llama a la notificación.

¿Cuál es el problema que ocurre en este escenario? Estoy usando xcode 9 Beta 5

Hassy
fuente

Respuestas:

190

Utilizar esta:

CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;

Para Swift, puede usar:

let keyboardSize = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.size
s.zainulabideen
fuente
1
Me salvaste el día
Helen Zhukova
1
Gracias, nunca pensé en eso
Ammar Hadzic
5
Cambiar de UIKeyboardFrameBeginUserInfoKey a UIKeyboardFrameEndUserInfoKey hizo el truco, gracias.
user2408952
Gracias, invertí medio día, pero no pude darme cuenta. gracias por salvarme el otro medio día.
Manish Nahar
@Akshay Simplemente startframe y endframe del teclado en los límites de pantalla respectivos.
s.zainulabideen
102

Reemplazar UIKeyboardFrameBeginUserInfoKey

con

UIKeyboardFrameEndUserInfoKey

El siguiente es de Apple Docs.

UIKeyboardFrameBeginUserInfoKey: la clave para un objeto NSValue que contiene un CGRect que identifica el marco de inicio del teclado en coordenadas de pantalla.

UIKeyboardFrameEndUserInfoKey: la clave de un objeto NSValue que contiene un CGRect que identifica el marco final del teclado en coordenadas de pantalla.

Aditya Srivastava
fuente
13
Apple necesita actualizar su código de ejemplo, porque ya no funciona en iOS 11. También de los documentos de Apple, donde usan UIKeyboardFrameBeginUserInfoKey: developer.apple.com/library/content/documentation/…
wildcat12
¡Resolvió mi problema! ¡Gracias por el consejo!
Ernie
¿Alguien puede explicarme como si tuviera 5 años cuál es la diferencia entre estos dos y por qué esto marca la diferencia cuando se trata de hacer que UIScrollView se desplace automáticamente? Realmente lo agradecería. ¡Gracias!
Mario
No funciona después de tocar un campo de texto con numPad. si después de numPad toco el campo de texto general, el teclado ya no está arriba y cuando descarta la vista baja
Jack Daniel
7

Prueba esto:

Reemplazar UIKeyboardFrameBeginUserInfoKeyconUIKeyboardFrameEndUserInfoKey

SolinLiu
fuente
1
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];el método keyboardWillChangeFrame: no solo se ejecuta una vez, tal vez dos o más. Tal vez algún teclado tenga una barra de herramientas especial en la parte superior a veces, el método se ejecutará muchas veces en este momento. Por lo tanto, debe reemplazar UIKeyboardFrameBeginUserInfoKey con UIKeyboardFrameEndUserInfoKey para obtener el marco final de el teclado.
SolinLiu
5

Tuve un problema similar al usar Xcode Versión 9.0 (9A235); aunque estaba usando Swift. En mi método keyboardWillShow escribí lo siguiente:

if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {

    let heightValue = keyboardSize.height    

    ...
}

Curiosamente, la primera vez que se llamó a keyboardWillShow, heightValue era 216.0, ¡pero durante llamadas posteriores se había convertido en 0! Quizás este sea un error de Xcode.

Reemplacé el UIKeyboardFrameBeginUserInfoKey con un UIKeyboardFrameEndUserInfoKey, y me solucionó el problema.

andym
fuente
1
Noté lo mismo. También parece que solo se aplica a la primera vez que se muestra el teclado. Los teclados en controladores de vista adicionales informaron la altura como 0 la primera vez que se mostró para ese controlador de vista.
jackofallcode
5

Este problema ocurre en iOS 11.

Reemplazar

"UIKeyboardFrameBeginUserInfoKey" con "UIKeyboardFrameEndUserInfoKey"

como se muestra a continuación solucionaría el problema

Código Objective-C:

CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;

Swift 2.3:

let keyboardSize = (NfnPsgVar.userInfo![UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue().size

Swift 3:

let keyboardSize = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.size
Sujay ONU
fuente
3

Calcule la altura del teclado usando el siguiente código.

Funciona tanto para los dispositivos con el área segura como para los dispositivos del área no segura.

Código:

@objc func keyboardWillShow(notification: Notification) {
    guard let keyboardFrame = notification.userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else {
            return
        }    
    let keyboardHeight: CGFloat                    
    if #available(iOS 11.0, *) {
       let window = UIApplication.shared.keyWindow
       let bottomPadding = window?.safeAreaInsets.bottom ?? 0.0
       keyboardHeight = keyboardFrame.cgRectValue.height - bottomPadding
    } else {
       keyboardHeight = keyboardFrame.cgRectValue.height
    }
}
Hitesh Surani
fuente
1

Su enfoque está tratando de obtener la altura del marco antes de que se muestre, y es por eso que debería ser 0, ¡lo cual no estoy seguro de por qué no es en el primer intento! Aquí hay un ejemplo de cómo obtener correctamente la altura del teclado en Swift 4.2:

func keyboardWillShow(notification: Notification) {

    guard let userInfo = notification.userInfo else { return }

    guard var keyboardFrame: CGRect = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else { return }

    keyboardFrame = view.convert(keyboardFrame, from: nil)

    let keyboardHeight = keyboardFrame.height
}

Esto proporcionará correctamente las propiedades del marco del teclado ANTES de que aparezca el teclado.

Ramin
fuente