Lavorando ad un’applicazione ho avuto la necessità di inserire una toolbar appena sopra la tastiera di iOS, per permettere all’utente di terminare l’inserimento di testo in una UITextField (ma si può applicare senza problemi anche ad altri componenti).
Questo comportamento viene utilizzato anche da Apple stessa, che spesso sopra la tastiera inserisce una barra (una toolbar appunto) con dei pulsanti quali “Prec.”, “Succ.”. Eccovi un esempio di ciò nell’app Safari:
Spulciando la documentazione e cercando in rete ho scoperto che esiste una proprietà che permette di implementare questa barra in maniera davvero molto veloce. Tale proprietà è “inputAccessoryView”, ed è presente, ad esempio, nelle classi UITextField e UITextView.
Per inserire questa barra dovremo semplicemente creare una UIToolbar con i pulsanti che desideriamo, e poi assegnarla come “inputAccessoryView” dell’oggetto con cui vogliamo che venga visualizzata. Il codice deve essere inserito in un metodo che viene richiamato all’inizio della modifica del componente in questione (ad es. il metodo textViewShouldBeginEditing: del protocollo UITextViewDelegate). Eccovi un esempio di codice:
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
// creaiamo la toolbar da inserire sopra la tastiera
UIToolbar *toolbar = [[UIToolbar alloc] init];
toolbar.frame = CGRectMake(0, 0, self.view.frame.size.width, 44.0);
toolbar.barStyle = UIBarStyleBlackTranslucent;
// creiamo il bottone per terminare l'inserimento
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(fineInserimentoNota:)];
UIBarButtonItem *spaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; // spazio per mantenere a dx il bottone Fine
NSMutableArray *items = [[NSMutableArray alloc] initWithObjects:spaceButton, doneButton, nil];
toolbar.items = items;
// settiamo la toolbar per aprirsi con la textview
self.textViewNote.inputAccessoryView = toolbar;
return YES;
}
Ed eccovi il risultato finale:
Ovviamente questo è solo uno dei possibili utilizzi di questa proprietà, gli altri li lascio alla vostra fantasia 😉
Alla prossima!!
20 comments On Inseriamo una Toolbar sopra la tastiera, la proprietà “inputAccessoryView”
Grazie 🙂
sto provando ad implementarla nei miei primi esperimenti… al momento mi ritorna un errore in debug su “fineInserimentoNota” ma sto sicuramente sbagliando io essendo un niubbo 🙂 … pensavo di sostituirlo con resignFirstResponder ma non va.
@Michele: Il metodo “fineInserimentoNota:” è un altro metodo che avevo definito, al suo interno avevo inserito solamente [self.textViewNote resignFirstResponder], come pensavi esattamente tu 😉
@AndreaBusi: grazie 1000 🙂 ora funziona correttamente.
Visto che ci sono, grazie anche per il tuo “Tutorial pratici per iOS SKD”, sia per l’opera in sé, sia per il fatto che la mantieni sempre aggiornata alle nuove release di xcode.
Grazie mille Michele 😉
@AndreaBusi: Grazie intanto per i tuoi tutorial molto utili. Sono uno dei possessori del tuo ebook. Volevo farti una domanda: ma se volessi aggiungere i pulsanti prec e succ come in safari, devo usare un segmentedControl?
@Marco: Ciao! Esattamente, con un segmented control ottieni quello che ti serve. Ti basterà assegnare un’azione al cambiamento di stato dell’oggetto e potrai così definire l’azione precedente o successivo 😉
@Andrea Busi: ho provato, ma sicuramente ho sbagliato qualcosa, ma non trovo il metodo per far andare il cursore al precedente o successivo!!! Come posso fare?
@Marco: Non penso ci siano dei metodi di default, io avevo gestito la cosa con due metodi miei, uno per “avanzare” di field e uno per “retrocedere”. In sostanza facevo una cosa del genere:
Questo per avanzare alla field successiva, una cosa analoga ma al contrario per tornare a quella precedente 😉
@Andrea, scusami se rispono solo ora..
Il metodo da te descritto funziona alla grande per passare il controllo alla textField successiva e precedente, ma ancora non riesco a creare il segmentedControl per la barra sopra la tastiera e il metodo che di sicuro sarà un selectedItemIndex.
Grazie ancora per gli utilissimi consigli.
@Andrea aggiungendo il segmentedControl all’array della toolBar, il simulatore mi da errore.. Perché?? Non ne vengo a capo..
Andrea
scusa il disturbo, sono riuscito a risolvere!!!!!
grazie mille andrea… come sempre non deludi mai!!!
ciao volevo sapere se invece di stare scritto:done o previous posso scivere fine e precedente-successivo
@Alessando: se utilizzi il bottone di default per “done” esso verrà tradotto in automatico in base alla lingua del dispositivo. In ogni caso puoi crearti un semplice bottone e inserire il nome che preferisci!
Ciao scusa il disturbo ma non ho capito mi da errore su fineInserimentoNota come mai non ho capito mi di e che non è stata trovata la property
Grazie
Ciao, “fineInserimentoNota:” è un metodo che devi aver definito nella tua classe. Se Xcode ti segnala un errore probabilmente hai dimenticato di definirlo oppure lo hai chiamato in modo diverso 🙂
Scusa sono alle prime armi devo definirlo nel file h o m
Come devo definirlo?
Non ho capito che azione deve fare
Grazie scusa la rottura
Basta nel file .m.
Dovrai avere un metodo come questo
Ciao allora io ho definito il metodo così:
– (void)fineInserimentoNota:(id)sender {
[self.Testo resignFirstResponder];
}
dove Testo è il mio uitextview definito nel fil h
così
ibaction uitextview *Testo;
pero quando clikko su done nel simulatore mi crasha e su questa riga mi da l’errore:
[self.Testo resignFirstResponder]; che non sono definite le proprety di Testo
Ti prego aiutami non riesco a venirne a capo
GRAZIE
Probabilmente sbagli ad impostare qualcosa. Qui trovi il sorgente dell’esempio 🙂
http://www.bubidevs.net/wp-content/uploads/2012/08/TestUITextView.zip