iOS 11: l'altezza della tastiera restituisce 0 nella notifica della tastiera


84

Ho utilizzato le notifiche della tastiera senza alcun problema e ho ottenuto l'altezza esatta della tastiera.

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

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

ma con iOS 11 la dimensione della tastiera è 0 quando viene chiamata la notifica.

Qual è il problema che si verifica in questo scenario? Sto usando xcode 9 Beta 5

Risposte:


190

Usa questo:

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

Per Swift, puoi utilizzare:

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

1
Mi hai salvato la giornata
Helen Zhukova

1
Grazie, non ci avrei mai pensato
Ammar Hadzic

5
Il passaggio da UIKeyboardFrameBeginUserInfoKey a UIKeyboardFrameEndUserInfoKey ha funzionato, grazie.
user2408952

Grazie, ho investito mezza giornata, ma non sono riuscito a capirlo. grazie per aver salvato la mia altra mezza giornata.
Manish Nahar

@Akshay Solo startframe e endframe della tastiera nei rispettivi limiti dello schermo.
s.zainulabideen

102

Sostituire UIKeyboardFrameBeginUserInfoKey

con

UIKeyboardFrameEndUserInfoKey

Quello che segue è di Apple Docs.

UIKeyboardFrameBeginUserInfoKey: la chiave per un oggetto NSValue contenente un CGRect che identifica il frame iniziale della tastiera nelle coordinate dello schermo.

UIKeyboardFrameEndUserInfoKey: chiave per un oggetto NSValue contenente un CGRect che identifica il fotogramma finale della tastiera nelle coordinate dello schermo.


13
Apple deve quindi aggiornare il codice di esempio, perché non funziona più su iOS 11. Anche dai documenti Apple, dove usano UIKeyboardFrameBeginUserInfoKey: developer.apple.com/library/content/documentation/…
wildcat12

Risolto il mio problema! Grazie per il consiglio!
Ernie

Qualcuno può spiegarmi come se avessi 5 anni qual è la differenza tra questi due e perché questo fa la differenza quando si tratta di far scorrere automaticamente l'UIScrollView? Lo apprezzerei davvero. Grazie!
Mario

Non funziona dopo aver toccato un campo di testo con numPad. se dopo numPad tocco il campo di testo generale, la tastiera non è più su e quando si chiude la vista abbassa
Jack Daniel

7

Prova questo:

Sostituisci UIKeyboardFrameBeginUserInfoKeyconUIKeyboardFrameEndUserInfoKey


1
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];il metodo keyboardWillChangeFrame: non viene eseguito solo una volta, forse due o più. Forse alcune tastiere hanno una barra degli strumenti speciale in alto a volte, il metodo verrà eseguito molte volte in questo momento.Quindi, dovresti sostituire UIKeyboardFrameBeginUserInfoKey con UIKeyboardFrameEndUserInfoKey per ottenere il fotogramma finale di la tastiera.
SolinLiu

5

Ho avuto un problema simile utilizzando Xcode versione 9.0 (9A235); anche se stavo usando Swift. Nel mio metodo KeyboardWillShow ho scritto quanto segue:

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

    let heightValue = keyboardSize.height    

    ...
}

Stranamente, la prima volta che keyboardWillShow è stato chiamato, heightValue era 216.0, ma durante le chiamate successive era diventato 0! Forse questo è un bug di Xcode.

Ho sostituito UIKeyboardFrameBeginUserInfoKey con un UIKeyboardFrameEndUserInfoKey e ha risolto il problema per me.


1
Ho notato la stessa cosa. Sembra anche che si applichi solo alla prima volta che viene visualizzata la tastiera. Le tastiere sui controller di visualizzazione aggiuntivi hanno riportato l'altezza come 0 la prima volta che è stata mostrata per quel controller di visualizzazione.
jackofallcode

5

Questo problema si verifica su iOS 11.

Sostituire

"UIKeyboardFrameBeginUserInfoKey" con "UIKeyboardFrameEndUserInfoKey"

come mostrato di seguito risolverebbe il problema

Codice 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

3

Calcola l'altezza della tastiera utilizzando il codice sottostante.

Funziona sia per i dispositivi con area sicura che per i dispositivi per area non sicura.

Codice:

@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
    }
}

2

Il tuo approccio sta cercando di ottenere l'altezza del fotogramma prima che venga mostrato, ed è per questo che dovrebbe essere 0, cosa che non sono sicuro perché non sia al primo tentativo! Ecco un esempio di come ottenere correttamente l'altezza della tastiera in 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
}

Ciò fornirà correttamente le proprietà della cornice della tastiera PRIMA che appaia la tastiera.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.