2012-05-25 14 views
9

Sto creando un'app simile all'app iMessage dell'iPad che esegue la messaggistica. Quindi c'è una vista di input ancorata nella parte inferiore della visualizzazione dei messaggi e la vista degli accessori di input quando viene mostrata la tastiera. Anche la visualizzazione dei messaggi deve essere ridimensionata correttamente quando la tastiera viene visualizzata mentre è agganciata o sganciata.Tastiera split per iPad

Il problema è che i dati di notifica provenienti da UIKeyboardWillChangeFrameNotification non sono coerenti.

In primo luogo, ci sono 3 modi in cui l'utente può sganciare la tastiera:

  1. Premere e tenere premuto il tasto in basso a destra, poi scivolare fino
  2. Premere e tenere premuto il tasto in basso a destra, quando il menu si apre, selezionare "sganciare"
  3. Premere e tenere premuto il tasto in basso a destra, quando il menu si apre, selezionare "split"

Per il caso # 1, i dati di notifica da UIKeyboardWillChangeFrameNotification è consistere ent. Ecco i dati:

userInfo = { 
    UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 0}, {768, 304}}"; 
} 

Per il caso # 2 e # 3 i dati sono incoerenti, ecco quello che ricevo:

userInfo = { 
    UIKeyboardAnimationCurveUserInfoKey = 0; 
    UIKeyboardAnimationDurationUserInfoKey = "0.25"; 
    UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {768, 304}}"; 
    UIKeyboardCenterBeginUserInfoKey = "NSPoint: {384, 872}"; 
    UIKeyboardCenterEndUserInfoKey = "NSPoint: {384, 1136}"; 
    UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 0}, {768, 304}}"; 
    UIKeyboardFrameChangedByUserInteraction = 0; 
    UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, -264}, {768, 304}}"; 
} 

Ciò che è strano è che quando ascolto per UIKeyboardDidChangeFrameNotification in caso 2 o 3, i dati arrivano come previsto:

userInfo = { 
    UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 0}, {768, 304}}"; 
} 

Perché i dati di notifica sono diversi? Qualcuno ha trovato un modo chiaro per rilevare gli eventi con tastiera divisa?

risposta

3

Nessun metodo chiaro no.

risolvo questo problema in fasi successive:

  1. Get orientamento corrente.
  2. Se l'orientamento è Orizzontale, ottengo l'altezza di UIKeyboardFrameEndUserInfoKey. deve essere uguale a 216. Significa che la tastiera è in modalità Split, altrimenti non;
  3. Se l'orientamento è Verticale, ottengo l'altezza di UIKeyboardFrameEndUserInfoKey. deve essere uguale a 216. Significa che la tastiera è in modalità Split, altrimenti non;

Aggiornamento mio gist for example. Con metodo convertRect.

+0

Questo renderà tutto più difficile da quando è stato introdotto iPad Mini. Non ho ancora toccato iOS 7 ancora ... –

+2

nessuna differenza. 216 non è pixel, il suo punto parmeter è indipendente dalla risoluzione. Ma questo non funziona con iPhone 4s e 5. E l'iPhone non ha una tastiera divisa. Cambiano il fattore di forma. – Bimawa

+0

Attenzione, questa non è una buona soluzione. Le altezze della tastiera cambiano a seconda delle impostazioni locali, della versione di iOS e del dispositivo. – capikaw

1

Questo è un modo un po 'hacky, ma affidabile per determinare se la tastiera è divisa.

NSArray *classPath = @[ 
    @"KeyboardAutomatic", 
    @"KeyboardImpl", 
    @"KeyboardLayoutStar", 
    @"KBKeyplaneView", 
    @"KBSplitImageView" 
]; 
UIView *splitView = textField.inputAccessoryView.superview; 
for (NSString *className in classPath) { 
    for (UIView *subview in splitView.subviews) { 
    if ([NSStringFromClass([subview class]) rangeOfString:className].location != NSNotFound) { 
     splitView = subview; 
     break; 
    } 
    } 
} 
BOOL isSplit = [splitView.subviews count] > 1; 

Ovviamente per questo funzioni è necessario un UITextField/UITextView con un non-nil inputAccessoryView (si può semplicemente utilizzare una vista vuoto per questo).

Nota: Il comportamento di textField.inputAccessoryView.superview è piuttosto schizzinoso, e di solito dipende dalla tastiera essendo stato visualizzato una volta prima di chiamare superview. Anche per passare il processo di invio di App Store ho rimosso il prefisso "UI" dai nomi delle classi private.Questa non è una garanzia Apple non contrassegnerà la tua app, ma questo approccio è stato usato con successo prima.

ho testato solo su iOS7, ma se non funziona su altre versioni di iOS approcci simili potrebbe essere utilizzato.

+0

questo potrebbe funzionare, ma perché accedi alle sottoview 0 0 1 0? –

+0

Perché attraversa la gerarchia della vista alla ricerca di una classe privata che rende effettivamente la tastiera. Ho usato [Reveal] (http://revealapp.com) per vedere lo stato della visualizzazione della tastiera. Vedi [qui] (http://imgur.com/v8rFMKP). – cagey

+0

È chiaramente una cattiva idea utilizzare questo codice esatto in produzione, ma si spera che la risposta possa ancora essere utile per alcune persone. – cagey

Problemi correlati