Passiamo adesso ad analizzare il comportamento dell'applicazione: come possiamo vedere toccando uno dei due TextField o la TextView apparirà la tastiera nella parte bassa dello schermo. Risultano evidenti due problemi: non riusciamo a mandare via la tastiera anche se tocchiamo il tasto return e la tastiera copre parte dell'area di testo della TextView non consento all'utente di leggere completamente i caratteri digitati. Andiamo a risolverli.
Rimuoviamo la tastiera dopo aver terminato l'inserimento del testo
Affinchè possa essere implementata questa funzionalità abbiamo bisogno di implementare, nel nostro InsertViewController
, due delegati: UITextFieldDelegate
e UITextViewDelegate
. Per il momento tralasciamo la definizione approfondita di cosa sia un delegato (che andremo a trattare più avanti); ci basti sapere che, implementando il delegato del TextField e della TextView saremo a conoscenza degli eventi associati a tali oggetti. Questo permetterà al nostro InsertViewController
di avere nuovi metodi per gestire gli eventi proprio su questi oggetti.
Per far ciò spostiamoci nel file InsertViewController.h ed associamo alla nostra classe i delegati necessari nel seguente modo:
@interface InsertViewController : UIViewController <UITextViewDelegate, UITextFieldDelegate>
Adesso la nostra classe è pronta per ricevere gli eventi dei TextField e della TextView. Non ci resta che associare a questi due elementi il nostro InsertViewController
come delegato andando ad agire sulla property delegate
degli oggetti nel seguente modo (aggiungendo rispettivamente questa linea prima dell'addSubView
di ogni oggetto):
_nameTextField.delegate = self;
_originTextField.delegate = self;
_descriptionTextView.delegate = self;
Come prima cosa implementiamo la possibilità di rimuovere la tastiera quando l'utente ha finito di modificare il testo. Avendo implementato il delegato UITextFieldDelegate
adesso abbiamo a disposizione nel FirstViewController
il metodo textFieldShouldReturn
che ci consentirà di capire quando l'utente tocca il tasto return della tastiera dopo aver inserito del testo all'interno di un TextField. Andiamo dunque ad inserire il seguente codice all'interno del file FirstViewController.m
:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
Quando un utente tocca un TextField, quest'ultimo entra nello stato di first responder ovvero è quell'oggetto che per primo riceve l'interazione con l'utente. Come possiamo vedere, all'interno del metodo di delegato, andiamo proprio ad agire su tale stato invocando il metodo resignFirstResponder
sul TextField che notificherà all'applicazione l'uscita dallo stato first responder. Da sottolineare è il fatto che l'oggetto UITextField
che ci viene passato come parametro al metodo textFieldShouldReturn:
è sempre il textField che è in stato first responder.
Passiamo adesso alla TextView. In questo caso andremo ad utilizzare il metodo di delegato textView: shouldChangeTextInRange: replacementText:
come segue:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text {
if([text language="isEqualToString:@"
""][/text]) {
[textView resignFirstResponder];
return NO;
}
return YES;
}
Il metodo di delegato sopra riportato, viene richiamato ogni qual volta l'utente digiti un tasto sulla tastiera virtuale. All'interno del metodo andiamo a contrallare se l'ultimo carattere inserito è uguale a \n
, ovvero il carattere di a capo ottenuto toccando il tasto return sulla tastiera, invocando il metodo isEqualToString
sulla stringa text
. Se il riscontro restituisce esito positivo, invochiamo il metodo resignFirstResponder
sulla TextView.
Tengo a precisare il fatto che la soluzione mostrata è una soluzione non ottimale, in quanto otterremo il comportamento voluto (mandare via la tastiera), ma inficeremo il comportamento standard della TextView. Questo perchè il corretto dismiss della tastiera dovrà essere eseguito con concetti (bottoni ed eventi associati) che andremo ad affrontare nelle prossime lezioni.
Spostiamo il contenuto della view per consentire la lettura del testo inserito nella TextView
Affinchè il testo nella TextView sia leggibile durante la digitazione è necessario traslare il contenuto di tutta la view verso l'alto. Per far ciò andremo ad utilizzare altri due metodi di delegato della TextView: textViewDidBeginEditing:
(richiamo quando la TextView diventa first responder) e il metodo textViewDidEndEditing:
(richiamato quando viene richiamato il metodo resignFirstResponder
sulla TextView).
- (void)textViewDidBeginEditing:(UITextView *)textView
{
CGAffineTransform translateUp = CGAffineTransformMakeTranslation(0.0, -150.0);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
self.view.transform = translateUp;
[UIView commitAnimations];
}
- (void)textViewDidEndEditing:(UITextView *)textView
{
CGAffineTransform translateUp = CGAffineTransformMakeTranslation(0.0, 0.0);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
self.view.transform = translateUp;
[UIView commitAnimations];
}
La spiegazione del codice all'interno di questi due metodi esula dai contenuti di questa guida, ma è stato tuttavia inserito, per permettere un corretto utilizzo dell'applicazione. Al lettore basti sapere che la funzione CGAffineTransformMakeTranslation(tx,ty)
riceve come parametri due valori di tipo CGFloat
che indicano di quanti pixel sarà spostato l'oggetto, rispettivamente sull'asse x e sull'asse y. Tale trasformata non modificherà il frame
dell'oggetto, ma applicherà su di esso solamente una trasformata e quindi per riportarlo nella posizione originaria dovremo applicare la trasformata CGAffineTransformMakeTranslation(0.0, 0.0)
.