Concludiamo la nostra prima applicazione implementando il controller.
Nella puntata precedente abbiamo disegnato la nostra interfaccia e lasciato che InterfaceBuilder scrivesse per noi le classi. A questo punto implementiamo il metodo che ci permetta di scrivere nella label il nostro saluto.
Una piccola considerazione prima di iniziare.
All'inizio abbiamo parlato di pattern MVC e abbiamo definito il Modello come l'oggetto che rappresenta i nostri dati. In questo esempio useremo un oggetto di tipo NSString, naturalmente non lo dovremo implementare, ma ricordiamoci che, nonostante sia molto semplice, è comunque un oggetto!
Apriamo il file dell'interfaccia e modifichiamolo come segue:
#import <UIKit/UIKit.h>
@interface testViewController : UIViewController <UITextFieldDelegate>{
IBOutlet UITextField * nome;
IBOutlet UILabel * saluto;
NSString * stringa;
}
@property (nonatomic, retain) UITextField *nome;
@property (nonatomic, retain) UILabel *saluto;
@property (nonatomic, copy) NSString *stringa;
- (IBAction)saluta:(id)sender;
@end
Analzziamo le parti in grassetto.
Innanzitutto la dichiarazione del nostro piccolo modello, ovvero la stringa di tipo NSString.
Ne altre tre righe sono un particolare meccanismo di Object-C chiamato Property. Una property ci aiuta a dichiarare i metodi getter e setter in automatico. Per esempio per nostra stringa avremo a disposizione i metodi [self string] e [self setString:@"stringa"], ma anche la possibilità di accedere alle proprietà tramite la dot-notation (per maggiori informazioni The Objective-C 2.0 Programming Language ).
Passiamo all'implementazione.
Iniziamo con l'esplicitare le proprietà, in Object-C per farlo viene usata la parola riservata @syntetize
@synthesize saluto,nome,stringa;
Passiamo all'implementazione del metodo -(IBAction)saluta:(id)sender;
- (IBAction)saluta:(id)sender {
/* Gestiamo il caso del pulsante premuto senza testo */
NSString *nome_string;
if ([self.nome.text length] == 0) {
nome_string = @"Mondo";
}else{
nome_string = self.nome.text;
}
/* Formattiamo la stringa per il saluto e la assegniamo al nostro modello */
self.stringa = [[NSString alloc] initWithFormat:@"Ciao %@!", nome_string];
/* Copiamo il modello nella label */
self.saluto.text = self.stringa;
}
Se lanciamo l'applicazione...

Ops... non si chiude la tastiera!
Come ovviare al problema? Nella puntata precedente abbiamo definito come delegate del campo di testo il nostro controller, questo è il momento di capire cosa questo voglia dire.
Abbiamo definito i delegate come degli oggetti che ricevono delle notifiche da parte degli altri oggetti. Ogni delegate rispecchia un protocollo e quello del file di testo è <UITextFieldDelegate>.
Se cerchiamo nella documentazione la definizione del protocollo troviamo il metodo che ci serve:
textFieldShouldReturn:
Asks the delegate if the text field should process the pressing of the return button. This method is optional.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
Parameters
- textField
-
The text field whose return button was pressed.
Return Value
YES if the text field should implement its default behavior for the return button; otherwise, NO.
Discussion
The text field calls this method whenever the user taps the return button. You can use this method to implement any custom behavior when the button is tapped.
Availability
- Available in iPhone OS 2.0 and later.
Declared In
UITextField.h
Il metodo in questione ritorna vero (YES) se la tastiera deve chiudersi oppure falso (NO) viceversa. Per ottenere il risultato desiderato indichiamo il protocollo nel file di intestazione e sovraccarichiamo il metodo nel'implementazione:
Nel file di intestazione...
@interface testViewController : UIViewController <UITextFieldDelegate>
...e nell'implementazione
-(BOOL)textFieldShouldReturn:(UITextField *)theTextField{
if (nome==theTextField){
[nome resignFirstResponder];
}
return YES;
}
In questo caso l'if non sarebbe stato necessario, la sua funzione è quella di controllare che chi ha chiamato il controllo sia il campo di testo per cui chiudere la tastiera. Avendone uno sarebbe bastato un semplice "return YES".
Lanciamo la nostra applicazione e godiamoci il risultato!
Ciao, se io inserisco un altro evento definito con IBAction allo stesso modo, che doverbbe svolgere un'altra operazione, questa secondo evento non lo trovo in INterface Builder, da collegare ad un qualsiasi altro pulsante. Non riesco a capire perché ciò accade, a voi è mai capitato?
<UITextFieldDelegate> è il protocollo che segue il controller ed è fondamentale, purtroppo l'editor di questo sito quando incontra < o > li considera tag e non trovandoli nella white list li cancella senza nemmeno avvisare mea culpa :)
E anche subito sotto sul tuo sito c'è scritto copy copy retain in ordine, mentre nei file scaricabili retain retain copy
Scaricando il tuo codice ho confrontato, ed ho capito che il problema è proprio nel file .h. Infatti la riga giusta è "@interface testViewController : UIViewController <UITextFieldDelegate>", e non @interface testViewController : UIViewController"..... Mancava un "<UITextFieldDelegate>"!!! Ti consiglio di correggere il post xkè sembrerebbe essere fondamentale! Grazie ancora
ho modificato la definizione del file .h, anche se quello postato è quello che viene fuori da interface builder, credo che questo sia un pò più corretto.
Mi posti il file .h? credo siano li i casini
Ho riprovato, ma guarda un po' che bei 5 errori mi vengono fuori... ho controllato tutto, ho seguito passo passo tutte le istruzioni. Dove sta il problema? Screenshot errori: http://img514.imageshack.us/img514/8339/immagine2qb3.png
Poco poco poco... che bella parola! :7)
Per esempio questo pezzo: " Iniziamo con l'esplicitare le proprietà, in Object-C per farlo viene usata la parola riservata @syntetize " Cosa vuol dire esplicitare le proprietà? Probabilmente è chiaro a chi conosce bene l'Odject-C, ma non a me che ho fatto solo un po' di C... Ad ogni modo mi sono ricreduto: la colpa è mia, non tua! E poi le cose poco chiare sono davvero poche, è solo che mi ero appena svegliato ed ero poco lucido! Ora riprovo a cimentarmi
Cercherò di sistemare la guida, in ogni caso mi potresti dire cosa trovi poco chiaro? Il progetto dell'applicazione lo metto online pomeriggio stesso :)
Ciao! Ti ringrazio molto per il tuo sito, ma devo dire che sinceramente la guida non è molto ben fatta, soprattutto le ultime pagine, nel senso che non sempre sei chiaro... E poi che ne dici di mettere online il file xCode di questa mini app?



Per risolvere il problema ho dovuto "sincronizzare" Interface Builder con il codice scritto in Xcode. Dopo aver selezionato "Read Class File" dal menù File, il nuovo evento che avevo aggiunto è risultato disponibile nel File's Owner. Tutto bene quel che finisce bene :)