UIPickerView e UIDatePicker – Guida all’uso
Nella guida di oggi approfondiremo un componente molto utilizzato all’interno delle applicazioni per iphone, stiamo parlando di UIPickerView (e UIDatePicker).
Lo studio di questi due oggetti ci permetterà di chiarire il concetto di delegate e di vedere all’opera il paradigma mvc (model-view-controller)
Diamo un’occhiata alla gerarchia delle classi per capire di cosa ci occupiamo oggi:
Come nostra consuetudine i nomi bordati in verde si riferiscono a classi già trattate su questo stesso sito [qui], mentre quelli bordati in rosso sono quelle che analizzeremo in questo articolo.
Concorderete con me che non c’è sistema migliore per studiare una classe se non quella di scaricare la class reference dal sito della apple, (ok, ok, a parte leggere il sorgente
) ecco quindi due link per un facile download:
UIPickerView Class Reference
UIDatePicker Class Reference
Iniziamo analizzando il più semplice tra i due, l’ UIDatePicker (che non necessita di delegate) trasciniamone uno su una view oppure inserendo questo codice per generarlo a runtime:
UIDatePicker *datePicker; datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 150, 0, 0)]; [self.view addSubview:datePicker];
da notare che non importano le dimensioni del frame, il picker ha dimensione fissa.
Vediamo quali sono le più comuni proprietà e metodi che questo oggetto ci mette a disposizione:
maximumDate & minimumDate:
@property(nonatomic, retain) NSDate *maximumDate @property(nonatomic, retain) NSDate *minimumDate
permettono di limitare il range di variabilità della data impostando la data massima e la data minima selezionabile. Di default vengono impostate entrambe a nil quindi l’utente può selezionare una data arbitrariamente passata o futura.
esempio: (questo esempio è complicato dall’utilizzo della classe nsdate che vedremo un’altra volta.)
NSString *min = @"20042010"; NSString *max = @"22042010"; NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; [dateFormat setDateFormat:@"ddMMyyyy"]; NSDate *datemin = [dateFormat dateFromString:min]; NSDate *datemax = [dateFormat dateFromString:max]; [self.view addSubview:datePicker]; datePicker.maximumDate = datemax; datePicker.minimumDate = datemin;
minuteInterval:
@property(nonatomic) NSInteger minuteInterval
Indica l’intervallo di selezione dei minuti, di default viene posto a 1 ma possiamo modificarlo, purché ci limitiamo ad inserire divisori di 60 (per esempio 2, 5, 30 ma non 23 oppure 45)
datePicker.minuteInterval = 30;
setDate:animated:
questo metodo permette di impostare una data nell’ UIDatePicker a runtime, se animated è impostato a YES verrà visualizzata l’animazione delle rotelle che girano.
datePickerMode:
@property(nonatomic) UIDatePickerMode datePickerMode</strong>
Questa proprietà determina l’aspetto delll’UIDatePicker, se permette la selezione di una data, di un orario, di entrambi o un conto alla rovescia. Il valore di default è UIDatePickerModeDateAndTime.
Gli altri possibili valori sono:
UIDatePickerModeTime UIDatePickerModeDate UIDatePickerModeDateAndTime UIDatePickerModeCountDownTimer
Veniamo ora al secondo argomento di questa guida, parliamo di UIPickerView.
Proviamo come poc’anzi a creare un pickerview e visualizzarlo nella nostra applicazione:
UIPickerView *Picker; Picker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 150, 0, 0)]; [self.view addSubview:Picker]; UIPickerView *Picker;Picker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 150, 0, 0)]; [self.view addSubview:Picker];
Purtroppo il codice sembra non funzionare, il picker non si vede ed al suo posto otteniamo soltato un rettangolo nero, come mai? Ci viene in aiuto la class reference che dice:
“A UIPickerView object requires the cooperation of a delegate for constructing its components and a data source for providing the numbers of components and rows.”
Che per chi non mastica l’inglese vuol dire:
“Un oggetto UIPickerView richiede la cooperazione di un degate per costruire i suoi componenti e di un data source che proveda a fornire il numero dei componenti e delle righe.”
Quindi poichè al nostro pickerview non abbiamo specificato nè delegate nè datasource, non è in grado di visualizzare nulla, ecco quindi spiegato il rettangolo nero.
Concettualmente delegate e dataprovider potrebbero essere due classi separate e create appositamente per tale scopo, ma spesso viene dato il compito di assolvere a questi ruoli allo stesso File’s Owner dell’uipickerview. Per fare questo quindi scriviamo:
[Picker setDelegate:self]; [Picker setDataSource:self];
Se provassimo adesso ad eseguire il codice vedremmo crashare inesorabilmente la nostra applicazione, ma anche a questo c’è una spiegazione… abbiamo detto al pickerview di interpellare il suo File’s Owner (self) per ricevere tutte le informazioni necessarie per la sua visualizzazione, ma non abbiamo detto al File’s Owner cosa rispondere, quindi in questo empasse l’applicazione va in crash.
Diamo quindi un’occhiata alla reference apple per UIPickerViewDelegate (qui)
scopriamo che la classe che vuol fare da delegare ad un uipickerview deve implementare almeno uno tra questi due metodi:
– pickerView:titleForRow:forComponent: – pickerView:viewForRow:forComponent:reusingView:
Il secondo è meno utilizzato perché si usa per visualizzare immagini all’interno del picker piuttosto che una descrizione testuale;
Aggiungiamo quindi alla nostra classe questo metodo:
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { return [NSString stringWithFormat:@"VALORE NUM:%d",row]; }
non abbiamo ancora terminato, abbiamo implementato il delegate, resta da implementare il datasource.
Leggiamo quindi sempre dalla reference apple (qui) che i metodi da implementare sono tutti e due, e sono:
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
Il primo specifica quante “rotelle” devono essere disegnate nel picker, mentre il secondo specifica, per ogni “rotella” quanti devono essere i valori presenti. Nel nostro caso possiamo quindi aggiungere:
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 1; } - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { return 20; }
eseguiamo quindi il nostro codice e godiamoci finalmente il nostro UIpickerView!
La trattazione di questi oggetti è stata particolarmente lunga e non è affatto esaustiva, invito per tanto tutti a leggere le reference apple per riuscire a sfruttare al massimo questi oggetti.
Un ultimo consiglio per gli amanti di interface builder, potete trascinare i picker come trascinereste qualsiasi altro oggetto, ricordatevi però di impostare nella finestra “connection” il corretto delegate e datasource (ctrl e trascina)
























grandissimo tutoria..:) non so come farei senza di voi….:) una cosa, sulle reference non mi sembra di aver trovato niente riguardo la personalizzazione della grafica. es: io avrei bisogno di rendere lo sfondo(quello grigio) trasparente ma non ci son ancora riuscito…