{"id":3148,"date":"2010-04-23T10:27:20","date_gmt":"2010-04-23T08:27:20","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=3148"},"modified":"2013-06-20T10:43:26","modified_gmt":"2013-06-20T08:43:26","slug":"uipickerview-e-uidatepicker-guida-all-uso","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/uipickerview-e-uidatepicker-guida-all-uso\/","title":{"rendered":"UIPickerView e UIDatePicker &#8211; Guida all&#8217;uso"},"content":{"rendered":"<p>Nella guida di oggi approfondiremo un componente molto utilizzato all&#8217;interno delle applicazioni per iphone, stiamo parlando di <strong>UIPickerView<\/strong> (e UIDatePicker).<br \/>\nLo studio di questi due oggetti ci permetter\u00e0 di chiarire il concetto di delegate e di vedere all&#8217;opera il paradigma mvc (model-view-controller)<br \/>\nDiamo un&#8217;occhiata alla gerarchia delle classi per capire di cosa ci occupiamo oggi:<\/p>\n<p><center><\/p>\n<div id=\"attachment_3149\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/gerarchia-uipickerview.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3149\" class=\"size-medium wp-image-3149\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/gerarchia-uipickerview-300x109.png\" alt=\"\" width=\"300\" height=\"109\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/gerarchia-uipickerview-300x109.png 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/gerarchia-uipickerview.png 567w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p id=\"caption-attachment-3149\" class=\"wp-caption-text\">Gerarchia delle classi UIPickerView e UIDatePicker<\/p>\n<\/div>\n<p><\/center><!--more--><\/p>\n<p>Come nostra consuetudine i nomi bordati in verde si riferiscono a classi gi\u00e0 trattate su questo stesso sito [<a href=\"http:\/\/alturl.com\/7yyp\" target=\"_blank\">qui<\/a>], mentre quelli bordati in rosso sono quelle che analizzeremo in questo articolo.<\/p>\n<p>Concorderete con me che non c&#8217;\u00e8 sistema migliore per studiare una classe se non quella di scaricare la <strong>class reference<\/strong> dal sito della apple, (ok, ok, a parte leggere il sorgente \ud83d\ude42 ) ecco quindi due link per un facile download:<\/p>\n<p><a href=\"http:\/\/alturl.com\/qo53\" target=\"_blank\">UIPickerView Class Reference<\/a><br \/>\n<a href=\"http:\/\/alturl.com\/gz7v\" target=\"_blank\">UIDatePicker Class Reference<\/a><\/p>\n<p>Iniziamo analizzando il pi\u00f9 semplice tra i due, l&#8217; <strong>UIDatePicker<\/strong> (che non necessita di delegate)\u00a0trasciniamone uno su una view oppure inserendo questo codice per generarlo a runtime:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\nUIDatePicker *datePicker;\r\ndatePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 150, 0, 0)];\r\n[self.view addSubview:datePicker];\r\n<\/pre>\n<p>da notare che non importano le dimensioni del frame, il picker ha dimensione fissa.<br \/>\nVediamo quali sono le pi\u00f9 comuni propriet\u00e0 e metodi che questo oggetto ci mette a disposizione:<\/p>\n<p><strong>maximumDate &amp; minimumDate:<\/strong><\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n@property(nonatomic, retain) NSDate *maximumDate\r\n@property(nonatomic, retain) NSDate *minimumDate\r\n<\/pre>\n<p>permettono di limitare il range di variabilit\u00e0 della data impostando la data massima e la data minima selezionabile. Di default vengono impostate entrambe a nil quindi l&#8217;utente pu\u00f2 selezionare una data arbitrariamente passata o futura.<\/p>\n<p>esempio: (questo esempio \u00e8 complicato dall&#8217;utilizzo della classe <em>nsdate<\/em> che vedremo un&#8217;altra volta.)<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\nNSString *min = @\"20042010\";\r\nNSString *max = @\"22042010\";\r\nNSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];\r\n[dateFormat setDateFormat:@\"ddMMyyyy\"];\r\nNSDate *datemin = [dateFormat dateFromString:min];\r\nNSDate *datemax = [dateFormat dateFromString:max];\r\n[self.view addSubview:datePicker];\r\ndatePicker.maximumDate = datemax;\r\ndatePicker.minimumDate = datemin;\r\n<\/pre>\n<p><strong>minuteInterval:<\/strong><\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n@property(nonatomic) NSInteger minuteInterval\r\n<\/pre>\n<p>Indica l&#8217;intervallo di selezione dei minuti, di default viene posto a 1 ma possiamo modificarlo, purch\u00e9 ci limitiamo ad inserire divisori di 60 (per esempio 2, 5, 30 ma non 23 oppure 45)<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\ndatePicker.minuteInterval = 30;\r\n<\/pre>\n<p><strong>setDate:animated:<\/strong><\/p>\n<p>questo metodo permette di impostare una data nell&#8217; UIDatePicker a runtime, se animated \u00e8 impostato a YES verr\u00e0 visualizzata l&#8217;animazione delle rotelle che girano.<\/p>\n<p><strong>datePickerMode<\/strong>:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n@property(nonatomic) UIDatePickerMode datePickerMode<\/strong>\r\n<\/pre>\n<p>Questa propriet\u00e0 determina l&#8217;aspetto delll&#8217;UIDatePicker, se permette la selezione di una data, di un orario, di entrambi o un conto alla rovescia. Il valore di default \u00e8 <em>UIDatePickerModeDateAndTime<\/em>.<\/p>\n<p>Gli altri possibili valori sono:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\nUIDatePickerModeTime\r\nUIDatePickerModeDate\r\nUIDatePickerModeDateAndTime\r\nUIDatePickerModeCountDownTimer\r\n<\/pre>\n<p><center><\/p>\n<table border=\"0\" align=\"center\">\n<tbody>\n<tr>\n<td>\n<div id=\"attachment_3155\" style=\"width: 166px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/UIDatePickerModeTime.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3155\" class=\"size-medium wp-image-3155\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/UIDatePickerModeTime-156x300.png\" alt=\"\" width=\"156\" height=\"300\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/UIDatePickerModeTime-156x300.png 156w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/UIDatePickerModeTime.png 386w\" sizes=\"auto, (max-width: 156px) 100vw, 156px\" \/><\/a><\/p>\n<p id=\"caption-attachment-3155\" class=\"wp-caption-text\">UIDatePickerModeTime<\/p>\n<\/div>\n<\/td>\n<td>\n<div id=\"attachment_3156\" style=\"width: 166px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/UIDatePickerModeDate.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3156\" class=\"size-medium wp-image-3156\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/UIDatePickerModeDate-156x300.png\" alt=\"\" width=\"156\" height=\"300\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/UIDatePickerModeDate-156x300.png 156w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/UIDatePickerModeDate.png 386w\" sizes=\"auto, (max-width: 156px) 100vw, 156px\" \/><\/a><\/p>\n<p id=\"caption-attachment-3156\" class=\"wp-caption-text\">UIDatePickerModeDate<\/p>\n<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<div id=\"attachment_3157\" style=\"width: 166px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/UIDatePickerModeDateAndTime.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3157\" class=\"size-medium wp-image-3157\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/UIDatePickerModeDateAndTime-156x300.png\" alt=\"\" width=\"156\" height=\"300\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/UIDatePickerModeDateAndTime-156x300.png 156w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/UIDatePickerModeDateAndTime.png 386w\" sizes=\"auto, (max-width: 156px) 100vw, 156px\" \/><\/a><\/p>\n<p id=\"caption-attachment-3157\" class=\"wp-caption-text\">UIDatePickerModeDateAndTime<\/p>\n<\/div>\n<\/td>\n<td>\n<div id=\"attachment_3158\" style=\"width: 166px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/UIDatePickerModeCountDownTimer.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3158\" class=\"size-medium wp-image-3158\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/UIDatePickerModeCountDownTimer-156x300.png\" alt=\"\" width=\"156\" height=\"300\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/UIDatePickerModeCountDownTimer-156x300.png 156w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/UIDatePickerModeCountDownTimer.png 386w\" sizes=\"auto, (max-width: 156px) 100vw, 156px\" \/><\/a><\/p>\n<p id=\"caption-attachment-3158\" class=\"wp-caption-text\">&#8230;ModeCountDownTimer<\/p>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><\/center><\/p>\n<p>Veniamo ora al secondo argomento di questa guida, parliamo di <strong>UIPickerView<\/strong>.<\/p>\n<p>Proviamo come poc&#8217;anzi a creare un pickerview e visualizzarlo nella nostra applicazione:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\nUIPickerView *Picker;\r\nPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 150, 0, 0)];\r\n[self.view addSubview:Picker];\r\n<\/pre>\n<p>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:<\/p>\n<p><em> &#8220;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.<\/em>&#8221;<\/p>\n<p>Che per chi non mastica l&#8217;inglese vuol dire:<\/p>\n<p>&#8220;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.&#8221;<\/p>\n<p>Quindi poich\u00e8 al nostro pickerview non abbiamo specificato n\u00e8 <strong>delegate<\/strong> n\u00e8 <strong>datasource<\/strong>, non \u00e8 in grado di visualizzare nulla, ecco quindi spiegato il rettangolo nero.<\/p>\n<p>Concettualmente <em>delegate<\/em> e <em>dataprovider<\/em> 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&#8217;s Owner dell&#8217;uipickerview. Per fare questo quindi scriviamo:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n[Picker setDelegate:self];\r\n[Picker setDataSource:self];\r\n<\/pre>\n<p>Se provassimo adesso ad eseguire il codice vedremmo crashare inesorabilmente la nostra applicazione, ma anche a questo c&#8217;\u00e8 una spiegazione&#8230; abbiamo detto al pickerview di interpellare il suo File&#8217;s Owner (self) per ricevere tutte le informazioni necessarie per la sua visualizzazione, ma non abbiamo detto al File&#8217;s Owner cosa rispondere, quindi in questo empasse l&#8217;applicazione va in crash.<\/p>\n<p>Diamo quindi un&#8217;occhiata alla reference apple per <strong>UIPickerViewDelegate<\/strong> (<a href=\"http:\/\/developer.apple.com\/iphone\/library\/documentation\/UIKit\/Reference\/UIPickerViewDelegate_Protocol\/Reference\/UIPickerViewDelegate.html#\/\/apple_ref\/occ\/intf\/UIPickerViewDelegate\" target=\"_blank\">qui<\/a>)<\/p>\n<p>scopriamo che la classe che vuol fare da delegare ad un uipickerview deve implementare almeno uno tra questi due metodi:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n\u2013 pickerView:titleForRow:forComponent:\r\n\u2013 pickerView:viewForRow:forComponent:reusingView:\r\n<\/pre>\n<p>Il secondo \u00e8 meno utilizzato perch\u00e9 si usa per visualizzare immagini all&#8217;interno del picker piuttosto che una descrizione testuale;<\/p>\n<p>Aggiungiamo quindi alla nostra classe questo metodo:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- (NSString *)pickerView:(UIPickerView *)pickerView\r\n\t\t\t titleForRow:(NSInteger)row\r\n\t\t\tforComponent:(NSInteger)component\r\n{\r\n\treturn [NSString stringWithFormat:@\"VALORE NUM:%d\",row];\r\n}\r\n<\/pre>\n<p>non abbiamo ancora terminato, abbiamo implementato il delegate, resta da implementare il datasource.<\/p>\n<p>Leggiamo quindi sempre dalla reference apple (<a href=\"http:\/\/developer.apple.com\/iphone\/library\/documentation\/iPhone\/Reference\/UIPickerViewDataSource_Protocol\/Reference\/Reference.html#\/\/apple_ref\/occ\/intf\/UIPickerViewDataSource\" target=\"_blank\">qui<\/a>) che i metodi da implementare sono tutti e due, e sono:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView\r\n- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component\r\n<\/pre>\n<p>Il primo specifica quante &#8220;rotelle&#8221; devono essere disegnate nel picker, mentre il secondo specifica, per ogni &#8220;rotella&#8221; quanti devono essere i valori presenti. Nel nostro caso possiamo quindi aggiungere:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView\r\n{\r\n\treturn 1;\r\n}\r\n- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component\r\n{\r\n\treturn 20;\r\n}\r\n<\/pre>\n<p>eseguiamo quindi il nostro codice e godiamoci finalmente il nostro UIpickerView!<\/p>\n<p><center><\/p>\n<div id=\"attachment_3163\" style=\"width: 166px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/pickerview.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3163\" class=\"size-medium wp-image-3163\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/pickerview-156x300.png\" alt=\"\" width=\"156\" height=\"300\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/pickerview-156x300.png 156w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/pickerview.png 386w\" sizes=\"auto, (max-width: 156px) 100vw, 156px\" \/><\/a><\/p>\n<p id=\"caption-attachment-3163\" class=\"wp-caption-text\">PickerView<\/p>\n<\/div>\n<p><\/center><\/p>\n<p>La trattazione di questi oggetti \u00e8 stata particolarmente lunga e non \u00e8 affatto esaustiva, invito per tanto tutti a leggere le reference apple per riuscire a sfruttare al massimo questi oggetti.<\/p>\n<p>Un ultimo consiglio per gli amanti di interface builder, potete trascinare i picker come trascinereste qualsiasi altro oggetto, ricordatevi per\u00f2 di impostare nella finestra &#8220;connection&#8221; il corretto delegate e datasource (ctrl e trascina)<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/supporto-applicazioni\/parole-vietate-di-ignazio-calo\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2264\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/02\/bannerIgnazioc.png\" alt=\"\" width=\"480\" height=\"100\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/02\/bannerIgnazioc.png 480w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/02\/bannerIgnazioc-300x62.png 300w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/a><br \/>\n<\/center><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nella guida di oggi approfondiremo un componente molto utilizzato all&#8217;interno delle applicazioni per iphone, stiamo parlando di&#8230;<\/p>\n","protected":false},"author":53,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[42],"tags":[42,198,43,164],"class_list":["post-3148","post","type-post","status-publish","format-standard","hentry","category-framework","tag-framework","tag-uidatepicker","tag-uikit","tag-uipickerview"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/3148","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/users\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=3148"}],"version-history":[{"count":17,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/3148\/revisions"}],"predecessor-version":[{"id":10588,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/3148\/revisions\/10588"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=3148"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=3148"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=3148"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}