{"id":1449,"date":"2010-01-06T09:30:37","date_gmt":"2010-01-06T08:30:37","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=1449"},"modified":"2010-01-06T18:37:05","modified_gmt":"2010-01-06T17:37:05","slug":"t020-creiamo-table-view-raggruppate-e-divise-in-sezioni","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/t020-creiamo-table-view-raggruppate-e-divise-in-sezioni\/","title":{"rendered":"T#020 &#8211; Creiamo Table View raggruppate e divise in sezioni"},"content":{"rendered":"<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/01\/t020_is_B.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/01\/t020_is_B.jpg\" alt=\"\" title=\"t020_is_B\" width=\"80\" height=\"120\" class=\"alignleft size-full wp-image-1568\" \/><\/a> Fino ad oggi <a href=\"http:\/\/www.devapp.it\/wordpress\/l005-table-views.html\" target=\"_blank\">abbiamo parlato e illustrato<\/a> solo teoricamente cosa sono e come si possono personalizzare le Table View, strumenti utili e praticamente indispensabili per la maggior parte delle applicazioni presenti in App Store. Oggi vedremo, con un esempio pratico, come creare una Table View, come popolarla con i nostri dati e come personalizzare e sfruttare alcune propriet\u00e0 offerte da questo tipo di oggetto. Creeremo quindi una tabella raggruppata e divisa in sezioni in modo da offrirvi una prima panoramica abbastanza ampia su questo argomento.<\/p>\n<p>Iniziamo con il nostro tutorial. Apriamo Xcode e creiamo un nuovo progetto. Dall&#8217;elenco dei template disponibili scegliamo &#8220;Navigation-based Application&#8221; e proseguiamo. Diamo un nome al nostro progetto, ad esempio &#8220;myTable&#8221;, scegliamo la posizione dove salvare e proseguiamo.<!--more--> In realt\u00e0, inconsapevolmente, abbiamo gi\u00e0 creato la nostra tabella, lavoro svolto automaticamente da Xcode grazie al template &#8220;Navigation-based&#8221; che ci fornisce un&#8217;interfaccia utente gi\u00e0 configurata con un navigation controller pronto a mostrare una lista di oggetti (ovvero i dati della nostra tabella che andremo ad inserire a breve). Apriamo il file <em>RootViewController.h<\/em> e andiamo a dichiarare gli elementi che ci serviranno nel nostro progetto:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n@interface RootViewController : UITableViewController {\r\n\r\n\tNSMutableArray *listaOggetti;\r\n\tNSMutableArray *listaDettaglioOggetti;\r\n}\r\n\r\n@end\r\n<\/pre>\n<p>Non abbiamo fatto altro che dichiarare due oggetti di tipo NSMutableArray chiamati rispettivamente <em>listaOggetti<\/em> e <em>listaDettaglioOggetti<\/em>. In listaOggetti memorizzeremo gli elementi della nostra tabella, mentre dentro listaDettaglioOggetti ci saranno i sottotitoli di ogni elemento della tabella stessa.<\/p>\n<p>Salviamo e passiamo al relativo file di implementazione <em>RootViewController.m<\/em> modificando il codice come segue. Iniziamo dal metodo viewDidLoad:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- (void)viewDidLoad {\r\n    [super viewDidLoad];\r\n\t\r\n\tlistaOggetti = [[NSMutableArray alloc] init];\r\n\t\r\n\tNSArray *arrayAnimali = [NSArray arrayWithObjects:@\"Cane\", @\"Gatto\", @\"Coniglio\", @\"Criceto\", @\"Cavallo\", nil];\r\n\tNSDictionary *dictAnimali = [NSDictionary dictionaryWithObject:arrayAnimali forKey:@\"Elementi\"];\r\n\r\n\tNSArray *arrayOggetti = [NSArray arrayWithObjects:@\"Armadio\", @\"Pentola\", @\"Ruota\", @\"iPhone\", nil];\r\n\tNSDictionary *dictOggetti = [NSDictionary dictionaryWithObject:arrayOggetti forKey:@\"Elementi\"];\r\n\t\r\n\tNSArray *arrayNomi = [NSArray arrayWithObjects:@\"Mario\", @\"Nicole\", @\"Simona\", @\"Daniel\", @\"Francesco\", nil];\r\n\tNSDictionary *dictNomi = [NSDictionary dictionaryWithObject:arrayNomi forKey:@\"Elementi\"];\r\n\t\r\n\t[listaOggetti addObject:dictAnimali];\r\n\t[listaOggetti addObject:dictOggetti];\r\n\t[listaOggetti addObject:dictNomi];\t\r\n\t\r\n\tlistaDettaglioOggetti = [[NSMutableArray alloc] init];\r\n\t\r\n\tNSArray *arrayDettaglioAnimali = [NSArray arrayWithObjects:@\"Animale 1\", @\"Animale 2\", @\"Animale 3\", @\"Animale 4\", @\"Animale 5\", nil];\r\n\tNSDictionary *dictDettaglioAnimali = [NSDictionary dictionaryWithObject:arrayDettaglioAnimali forKey:@\"dettaglioElementi\"];\r\n\t\r\n\tNSArray *arrayDettaglioOggetti = [NSArray arrayWithObjects:@\"Oggetto 1\", @\"Oggetto 2\", @\"Oggetto 3\", @\"Oggetto 4\", nil];\r\n\tNSDictionary *dictDettaglioOggetti = [NSDictionary dictionaryWithObject:arrayDettaglioOggetti forKey:@\"dettaglioElementi\"];\r\n\t\r\n\tNSArray *arrayDettaglioNomi = [NSArray arrayWithObjects:@\"Nome 1\", @\"Nome 2\", @\"Nome 3\", @\"Nome 4\", @\"Nome 5\", nil];\r\n\tNSDictionary *dictDettaglioNomi = [NSDictionary dictionaryWithObject:arrayDettaglioNomi forKey:@\"dettaglioElementi\"];\r\n\t\r\n\t[listaDettaglioOggetti addObject:dictDettaglioAnimali];\r\n\t[listaDettaglioOggetti addObject:dictDettaglioOggetti];\r\n\t[listaDettaglioOggetti addObject:dictDettaglioNomi];\r\n\t\r\n\tself.navigationItem.title = @\"T#020 - TableView in sezioni\";\r\n}\r\n<\/pre>\n<p>In questo modo non facciamo altro che sfruttare gli oggetti NSArray e NSDictionary per memorizzare i nostri dati (con &#8220;dettaglio&#8221; intendiamo i sottotitoli) che verranno poi mostrati e organizzati a dovere nella nostra tabella. Con l&#8217;ultima istruzione &#8220;self.navigationItem.title = @&#8221;T#020 &#8211; TableView in sezioni&#8221;;&#8221; settiamo semplicemente il titolo mostrato nella barra di navigazione in alto nella view.<\/p>\n<p>Impostiamo il metodo <em>numberOfSectionsInTableView<\/em> facendo calcolare automaticamente al programma il numero di sezioni della tabella tramite <em>listaOggetti<\/em>:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {\r\n    return [listaOggetti count];\r\n}\r\n<\/pre>\n<p>Impostiamo quindi il numero di righe nelle sezioni della tabella:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {\r\n\tNSDictionary *dictionary = [listaOggetti objectAtIndex:section];\r\n\tNSArray *array = [dictionary objectForKey:@\"Elementi\"];\r\n\treturn [array count];\r\n}\r\n<\/pre>\n<p>Inseriamo ora due metodi che serviranno a mostrare il titolo nell&#8217;header e il testo nel footer di ogni sezione:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{\r\n\tswitch (section) {\r\n\t\tcase 0:\r\n\t\t\treturn @\"Animali\";\r\n\t\t\tbreak;\r\n\t\tcase 1:\r\n\t\t\treturn @\"Oggetti\";\r\n\t\t\tbreak;\r\n\t\tcase 2:\r\n\t\t\treturn @\"Nomi\";\r\n\t\t\tbreak;\r\n\t\tdefault:\r\n\t\t\treturn nil;\r\n\t\t\tbreak;\r\n\t}\r\n}\r\n\r\n- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{\r\n\tswitch (section) {\r\n\t\tcase 0:\r\n\t\t\treturn @\"Footer Sezione Animali\";\r\n\t\t\tbreak;\r\n\t\tcase 1:\r\n\t\t\treturn @\"Footer Sezione Oggetti\";\r\n\t\t\tbreak;\r\n\t\tcase 2:\r\n\t\t\treturn @\"Footer Sezione Nomi\";\r\n\t\t\tbreak;\r\n\t\tdefault:\r\n\t\t\treturn nil;\r\n\t\t\tbreak;\r\n\t}\r\n}\r\n<\/pre>\n<p>Impostiamo ora l&#8217;altezza delle nostre celle tramite il metodo <em>heightForRowAtIndexPath<\/em>:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {\r\n\treturn 50;\r\n}\r\n<\/pre>\n<p>Anche se per questo tutorial \u00e8 totalmente inutile vediamo come impostare un accessorio &#8220;tipo&#8221; per le tabelle,  il <em>DisclosureIndicator<\/em> (ovvero la &#8220;freccettina a destra&#8221; utile per indicare all&#8217;utente che cliccando su una voce con questo accessorio si aprir\u00e0 un&#8217;altra vista):<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath {\t\r\n\treturn UITableViewCellAccessoryDisclosureIndicator;\r\n}\r\n<\/pre>\n<p>Questo \u00e8 solo uno degli accessori disponibili, vedremo nei futuri tutorial come impostare gli altri tipi disponibili e come arrivare ad implementare un&#8217;eventuale ulteriore vista di dettaglio in base a selezione di una specifica riga della tabella da parte dell&#8217;utente.<\/p>\n<p>Vediamo ora il metodo vero e proprio che useremo per riempire la tabella:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {\r\n    \r\n    static NSString *CellIdentifier = @\"Cell\";\r\n    \r\n    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];\r\n    if (cell == nil) {\r\n        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];\r\n\t\tcell.selectionStyle = UITableViewCellStyleSubtitle;\r\n\t}\r\n    \r\n\t\/\/ Configure the cell.\r\n\t\r\n\tNSDictionary *dictionary = [listaOggetti objectAtIndex:indexPath.section];\r\n\tNSArray *array = [dictionary objectForKey:@\"Elementi\"];\r\n\tNSString *cellValue = [array objectAtIndex:indexPath.row];\r\n\t\r\n\tNSDictionary *dettaglioDictionary = [listaDettaglioOggetti objectAtIndex:indexPath.section];\r\n\tNSArray *dettaglioArray = [dettaglioDictionary objectForKey:@\"dettaglioElementi\"];\r\n\tNSString *dettaglioCellValue = [dettaglioArray objectAtIndex:indexPath.row];\r\n\t\r\n\tcell.textLabel.text = cellValue;\r\n\tcell.detailTextLabel.text = dettaglioCellValue;\r\n\tcell.backgroundColor = [UIColor whiteColor];\r\n\tcell.selectionStyle = UITableViewCellSelectionStyleBlue;\r\n\t\r\n\tNSString *nomeImmagine = [NSString stringWithFormat:@\"logo.png\"];\r\n\t[[cell imageView] setImage:[UIImage imageNamed:nomeImmagine]];\r\n\t\r\n    return cell;\r\n}\r\n<\/pre>\n<p>Come vedete abbiamo inizializzato la tabella in modo che la struttura sia quella con i sottotitoli tramite le istruzioni &#8220;<em>initWithStyle:UITableViewCellStyleSubtitle<\/em>&#8221; e &#8220;<em>cell.selectionStyle = UITableViewCellStyleSubtitle;<\/em>&#8220;.<\/p>\n<p>Dopodich\u00e8 utilizziamo due oggetti di tipo <em>NSString<\/em> per memorizzare nel primo i nostri elementi (prelevati da listaOggetti) e nel secondo i rispettivi sottotitoli (presi da listaDettaglioOggetti) che mostreremo poi nella tabella, tramite le propriet\u00e0 <em>text<\/em> di textLabel e detailTextLabel delle celle.<\/p>\n<p>Impostiamo quindi il colore di sfondo delle celle e il loro stile durante la selezione (nel nostro caso verranno evidenziate in blu quando l&#8217;utente ne selezioner\u00e0 una).<\/p>\n<p>Le ultime due istruzioni prima di ritornare la nostra cella servono ad inserire un&#8217;immagine sulla sinistra. In questo semplice tutorial abbiamo immesso un&#8217;unica immagine valida per ogni cella, ma nulla ci vieta di averne una diversa per ogni riga della tabella, vedremo anche questo con uno dei prossimi tutorial.<\/p>\n<p>Come ultima cosa non dimentichiamoci di effettuare un release di listaOggetti e di listaDettaglioOggetti al fine di liberare la memoria utilizzata dal programma nel nostro dispositivo:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- (void)dealloc {\r\n\t[listaOggetti release];\r\n\t[listaDettaglioOggetti release];\r\n        [super dealloc];\r\n}\r\n<\/pre>\n<p>Con il codice \u00e8 tutto, salvate e avviate tramite &#8220;Build &#038; Go&#8221; l&#8217;applicazione nel simulatore o direttamente nel vostro iPhone. Quello che otterrete \u00e8 qualcosa di simile a quanto mostrato in figura qui sotto. Una tabella divisa per sezioni ti tipo &#8220;Plain&#8221;, non ancora divisa quindi in raggruppamenti.<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/01\/t020_IB_plain.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/01\/t020_IB_plain.png\" alt=\"\" title=\"t020_IB_plain\" width=\"386\" height=\"742\" class=\"aligncenter size-full wp-image-1575\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/01\/t020_IB_plain.png 386w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/01\/t020_IB_plain-156x300.png 156w\" sizes=\"auto, (max-width: 386px) 100vw, 386px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Per modificare la struttura della tabella da &#8220;Plain&#8221; a &#8220;Grouped&#8221; dobbiamo semplicemente aprire il file &#8220;RootViewController.xib&#8221; emodificare la propriet\u00e0 &#8220;Styles&#8221; negli &#8220;Attributes&#8221;:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/01\/t020_IB.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/01\/t020_IB.jpg\" alt=\"Tutorial 020 - UITable Plain\" title=\"t020_IB\" width=\"287\" height=\"182\" class=\"aligncenter size-full wp-image-1576\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Si pu\u00f2 quindi salvare, chiudere Interface Builder e ricompilare ed eseguire l&#8217;applicazione per ottenere questo risultato:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/01\/t020_is.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/01\/t020_is.jpg\" alt=\"Tutorial 020 - UITable Grouped\" title=\"t020_is\" width=\"320\" height=\"480\" class=\"aligncenter size-full wp-image-1577\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/01\/t020_is.jpg 320w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/01\/t020_is-200x300.jpg 200w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Come vedete siamo stati in grado di definire via codice sia elementi relativi all&#8217;aspetto grafico della nostra tabella, che ovviamente tutto ci\u00f2 che concerne i dati rappresentati da essa. Abbiamo usato oggetti diversi, come NSArray, NSDictionary e NSString per il caricamento dei dati nelle tabelle, ovviamente questo \u00e8 solo un esempio, potevate tranquillamente usare semplici array come potete prelevare dati da un database o da un sito web, con tecniche appena pi\u00f9 complesse che vedremo pi\u00f9 avanti.<\/p>\n<p>Approfondiremo con i prossimi tutorial altri aspetti legati all&#8217;utilissimo e interessantissimo mondo delle tabelle \ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Fino ad oggi abbiamo parlato e illustrato solo teoricamente cosa sono e come si possono personalizzare le&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[5,4,69,1,27],"class_list":["post-1449","post","type-post","status-publish","format-standard","hentry","category-tutorial-pratici","tag-objective-c","tag-programmazione","tag-table-view","tag-tutorial-pratici","tag-uitableview"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/1449","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\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=1449"}],"version-history":[{"count":16,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/1449\/revisions"}],"predecessor-version":[{"id":1608,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/1449\/revisions\/1608"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=1449"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=1449"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=1449"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}