Allinea in modo programmatico una barra degli strumenti sopra la tastiera dell'iPhone


94

In molti casi voglio aggiungere una barra degli strumenti nella parte superiore della tastiera dell'iPhone (come in iPhone Safari quando navighi tra gli elementi del modulo, ad esempio).

Attualmente sto specificando il rettangolo della barra degli strumenti con costanti, ma poiché altri elementi dell'interfaccia sono in movimento - barre degli strumenti e barre di navigazione nella parte superiore dello schermo - ogni volta che apportiamo una piccola modifica all'interfaccia, la barra degli strumenti non è allineata.

C'è un modo per determinare a livello di codice la posizione della tastiera in relazione alla visualizzazione corrente?

Risposte:


142

A partire da iOS 3.2 c'è un nuovo modo per ottenere questo effetto:

UITextFieldse UITextViewshanno una inputAccessoryViewproprietà, che puoi impostare su qualsiasi vista, che viene visualizzata automaticamente sopra e animata con la tastiera.

Nota che la vista che usi non dovrebbe essere nella gerarchia della vista altrove, né dovresti aggiungerla a qualche superview, questo è fatto per te.


fammi provare . Anche se sembra il modo migliore.
harshalb

Wow. Che scoperta! Grazie (l'ho fatto nel modo più duro ed è disordinato)
levous

1
Ho una UIToolbar con un UITextField all'interno di uno dei suoi pulsanti della barra, ma anche se ho impostato textFields inputAccessoryView su quella barra degli strumenti alla prima pressione la barra degli strumenti si alza ma non viene visualizzata alcuna tastiera. Alla seconda pressione compare la tastiera con la barra degli strumenti, qualche idea in merito?
Ugur Kumru,

Ma come aggiungere una barra degli strumenti su UIWebView? :(
Dmitry

L'ho fatto sostituendo i pulsanti sulla barra degli strumenti standard di UIWebView (lo stesso codice per rimuoverlo).
Dmitry

72

Quindi in poche parole:

Nel metodo init:

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil];
[nc addObserver:self selector:@selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil];

E poi hanno i metodi di cui sopra per regolare la posizione della barra:

-(void) keyboardWillShow:(NSNotification *) note
{
    CGRect r  = bar.frame, t;
    [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &t];
    r.origin.y -=  t.size.height;
    bar.frame = r;
}

Potrebbe renderlo carino animando il cambio di posizione avvolgendolo

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];
//...
    [UIView commitAnimations];

Stamattina stavo frugando tra le mie vecchie cose e ho notato che questa è una risposta molto migliore e più completa. Grazie!
Rob Drimmie

Questa risposta è ancora abbastanza rilevante più di un anno dopo. Mi ha aiutato a superare la gobba quando ho sviluppato qualcosa correlato a questo.
james_womack

2
Solo un avvertimento per le persone che si imbattono in questa domanda ora: UIKeyboardBoundsUserInfoKey è ora deprecato in iPhone OS 3.2. Ce ne sono altri simili come quelli UIKeyboardFrameBeginUserInfoKeyche danno le stesse informazioni.
Stephen Darlington

9
C'è anche un nuovo modo migliore per farlo in iOS3.2 la proprietà inputAccessoryView su UITextField e UITextView.
tonklon

6
Questa risposta ha aiutato moltissimo ma è un po 'datata. Dovresti usare UIKeyboardFrameEndUserInfoKeyper ottenere il fotogramma finale (nelle coordinate dello schermo) della tastiera. È inoltre possibile utilizzare UIKeyboardAnimationDurationUserInfoKeye UIKeyboardAnimationCurveUserInfoKeyper ottenere il resto dei parametri necessari per abbinare esattamente il comportamento della tastiera.
Dave Peck

60

Questo si basa sulla risposta esistente di tonklon : sto solo aggiungendo uno snippet di codice che mostra una barra degli strumenti nera semitrasparente nella parte superiore della tastiera, insieme a un pulsante "fatto" sulla destra:

UIToolbar *toolbar = [[[UIToolbar alloc] init] autorelease];
[toolbar setBarStyle:UIBarStyleBlackTranslucent];
[toolbar sizeToFit];

UIBarButtonItem *flexButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *doneButton =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(resignKeyboard)];

NSArray *itemsArray = [NSArray arrayWithObjects:flexButton, doneButton, nil];

[flexButton release];
[doneButton release];
[toolbar setItems:itemsArray];

[aTextField setInputAccessoryView:toolbar];

e l' -resignKeyboardaspetto come:

-(void)resignKeyboard {
  [aTextField resignFirstResponder];
}

Spero che aiuti qualcuno.


2
Aggiungo solo un piccolo commento su come mettere in atto il successivo precedente. UISegmentedControl * segmentControl = [[UISegmentedControl alloc] initWithItems: [NSArray arrayWithObjects: @ "Previous", @ "Next", nil]]; [segmentControl setSegmentedControlStyle: UISegmentedControlStyleBar]; [segmentControl addTarget: self action: @selector (nextPrevious :) forControlEvents: UIControlEventValueChanged];
Trausti Thor

1
Un'aggiunta al commento di @ TraustiThor: devi racchiudere il controllo segmentato in un UIBarButtonItem per aggiungerlo alla barra degli strumenti.
Tim Büthe

Eccellente: questo è tutto il codice di cui avevo bisogno. Grazie per la pubblicazione :)
Allunga il

Ma per quanto riguarda UIWebView? Come si aggiunge una barra degli strumenti?
Dmitry

24

Se ti registri per le notifiche della tastiera, ad esempio UIKeyboardWillShowNotification UIKeyboardWillHideNotification, ecc., La notifica che riceverai conterrà i limiti della tastiera nel userInfodict (UIKeyboardBoundsUserInfoKey ).

Vedi il UIWindowriferimento alla classe.


16

In 3.0 e versioni successive è possibile ottenere la durata e la curva dell'animazione dal file userInfo dizionario delle notifiche.

ad esempio, per animare le dimensioni della vista per fare spazio alla tastiera, registrarsi per UIKeyboardWillShowNotificatione fare qualcosa di simile a quanto segue:

- (void)keyboardWillShow:(NSNotification *)notification
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];

    CGRect frame = self.view.frame;
    frame.size.height -= [[[notification userInfo] objectForKey:UIKeyboardBoundsUserInfoKey] CGRectValue].size.height;
    self.view.frame = frame;

    [UIView commitAnimations];
}

Fai un'animazione simile per UIKeyboardWillHideNotification.


Sembra un modo migliore per farlo su 3.0 SDK grazie per la pubblicazione!
Hua-Ying

Grazie per il codice. Questo aiuta molto. Ma quando imposto il mio UITextView per diventare il primo risponditore nel viewDidLoad, l'UIToolBar non si muove con il ridimensionamento di self.view. Hai idea del perché?
RyanJM

1
@ RyanJM: diventaFirstResponder e resignFirstResponder hanno un comportamento strano quando la visualizzazione è fuori schermo. Dovresti invece chiamare getsFirstResponder dal tuo metodo viewWillAppear.
David Beck

0

Crea questo metodo e chiamalo su ViewWillLoad:

        - (void) keyboardToolbarSetup
{
    if(self.keyboardToolbar==nil)
        {
        self.keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];

        UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStylePlain target:self action:@selector(anyAction)];

        UIBarButtonItem *extraSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

        UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(anyOtherAction)];


        NSArray *toolbarButtons = [[NSArray alloc]initWithObjects:cancelButton,extraSpace,doneButton, nil];

        [self.keyboardToolbar setItems:toolbarButtons];

        self.myTextView.inputAccessoryView=self.keyboardToolbar;
        }
}

-3

Non c'è modo (AFAIK) per ottenere le dimensioni della visualizzazione della tastiera. Tuttavia è costante, almeno in ogni versione di iPhone finora.

Se calcoli la posizione della barra degli strumenti come un offset dalla PARTE INFERIORE della tua vista e prendi in considerazione le dimensioni della tua vista, non dovresti preoccuparti se una barra di navigazione è presente o meno.

Per esempio

#define KEYBOARD_HEIGHT 240 // example - can't remember the exact size
#define TOOLBAR_HEIGHT 30

toolBarRect.origin.y = viewRect.size.height - KEYBOARD_HEIGHT - TOOLBAR_HEIGHT;

// move toolbar either directly or with an animation

Invece di una definizione, potresti facilmente creare un file keyboardHeight funzione che restituisca la dimensione in base alla visualizzazione della tastiera e spostare il posizionamento di questa barra degli strumenti in una funzione separata che riorganizza il layout.

Inoltre può dipendere da dove si esegue questo posizionamento poiché è possibile che le dimensioni della visualizzazione cambino tra il caricamento e la visualizzazione in base alla configurazione della barra di navigazione. Credo che il posto migliore per farlo sarebbe in viewWillAppear.


Ha funzionato benissimo, grazie! Finora ho eseguito questo calcolo nel selettore attivato da UIKeyboardDidShowNotification. Ho provato solo in un paio di posti, ma sembra un buon posto.
Rob Drimmie

A partire dalla versione 5.0 la dimensione della tastiera non è più statica.
Alastair Stuart
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.