Quando è necessario mostrare una serie di elementi, rendendo possibile la selezione di uno di essi per una successiva “sotto lista” da visualizzare, è necessario ricorrere all’oggetto UITableView.
UITableView è responsabile della visualizzazione della lista di elementi a schermo, mentre la navigazione tra le liste di elementi visualizzate viene gestita da UINavigationController. Entrambi gli oggetti cooperano per ottenere l’effetto tipico delle applicazioni iPhone:

Creiamo un nuovo progetto, selezionando come template Window-based Application ed effettuando tutte le operazioni descritte in precedenza per ottenere un’applicativo base. Aggiungiamo, quindi una nuova classe controllore, denominata: MyTableViewController. Assicuratevi che l’opzione “With XIB for userinterface” sia disabilitata.

Data Source
Dal momento che vogliamo mostrare una lista di elementi all’interno della nostra nuova table view, abbiamo bisogno di una qualche forma di “sorgente dati” responsabile del mantenimento dei nostri dati e capace di fornire questi valori alla table view. La sorgente di dati puo’ essere di qualsiasi forma: XML, Databases, Array. Per i nostri esempi, ci baseremo su sorgenti di dati riconducibili alla classe NSMutableArray. Quest’ultimo, infatti, puo’ essere riempito con dati provenienti da svariate sorgenti (Internet URL, Databases, XML Files).
La prima cosa da fare e’ costruire una sorgente dati e popolarla con gli elementi che dobbiamo mostrare a schermo. Ci verra’ in aiuto un nuovo metodo, presente in tutte gli oggetti che ereditano da UIViewController: viewDidLoad. Questo metodo viene invocato non appena la property view della nostra classe viene caricata in memoria.

L’array aggiunto tra le variabili di interfaccia verra’ allocato dal metodo anticipato sopra e verra’ distrutto in fase di deallocazione dell’oggetto. All’interno del metodo viewDidLoad, inoltre, verranno caricati dei semplici elementi da visualizzare successivamente.


Configurare il numero di righe nella nostra tableView
La prima cosa da fare, visto che stiamo dialogando con un oggetto che deve mostrare un numero prestabilito di elementi, e’ fornire il numero di elementi da mostrare. Quest’operazione viene effettuata invocando il metodo tableView:numberOfRowsInSection. Il metodo ritorna un intero che indica il numero di righe (elementi) presenti nella nostra sorgente di dati. Visto che la nostra sorgente di dati e’ un array, possiamo ritornare il numero di elementi presenti nell’array.

La funzione autogenerata per noi dal template ritorna un intero pari a zero. Questo comportamento verra’ sostituito dalla nostra nuova istruzione che conta il numero di elementi presenti nell’array creato precedentemente.
Mostrare i nostri dati
Adesso e’ possibile mostrare i nostri dati a schermo. La table view conosce il numero di elementi da visualizzare ed abbiamo una sorgente di dati (NSMutableArray) pronta a fornire gli elementi richiesti. Quello che serve, quindi, e’ un metodo che “chieda” le informazioni corrette.

Quest’operazione viene effettuata dal metodo tableView:cellForRowAtIndexPath. Esso viene chiamato n volte; tante quanti sono gli elementi da visualizzare. Ogni volta, viene passato un parametro indexPath diverso. Attraverso il parametro indexPath, possiamo ottenere il numero della riga corrente da visualizzare. Il template genera per noi uno scheletro perfetto per il nostro scopo. L’unica cosa che dovremo modificare sara’ la riga responsabile della visualizzazione del nostro dato a schermo.

Creazione di una vista di dettaglio
Aggiungiamo una classe UIView al nostro progetto e chiamiamola DetailView.

Aggiungiamo adesso un controllore per questa nuova view e chiamiamolo DetailViewController.

I dati che verranno mostrati dalla nostra view, dipendono da quelli che abbiamo disponibili e da quelli che vogliamo realmente mostrare all’utente. Per il nostro esempio, sara’ sufficiente aggiungere un campo di testo, contenente il nome della nazione selezionata.

Nota come la variabile countryName sia stata configurata con un setter ed un getter automatici. Questo ci permettera’ di rendere piu’ agevole (e leggibile) il nostro codice piu’ avanti.
La parte implementativa si occupa semplicemente di inizializzare e mostrare correttamente a schermo l’oggetto UILabel e la sua UIView relativa.

Il nostro oggetto UIViewController, a sua volta, conterra’ un’oggetto di tipo DetailView nella sua dichiarazione d’interfaccia. Anche in questo caso abbiamo creato i metodi di getter e setter in maniera automatica, attraverso l’utilizzo della coppia @property / @synthesize.

La parte implementativa si preoccupera’ di creare ed inizializzare correttamente il view controller e gli oggetti ad esso legati (UIView).

Passaggio di dati
Per finire, dobbiamo completare il passaggio di dati dalla nostra tableView alla nostra nuova UIViewController e visualizzarne il risultato a schermo. Per fare questo, utilizziamo il metodo tableView:didSelectRowAtIndexPath. Utilizzando la variabile indexPath, selezioniamo la riga appropriata dalla nostra sorgente di dati (NSMutableArray) e passiamo il risultato alla classe DetailView, per aggiornare il valore della sua variabile countryName.

Configurazione della view con accessoryType
Adesso la nostra applicazione permette di visualizzare dei risultati selezionando un elemento dalla nostra tabella. Il fatto di avere dati ulteriori da visualizzare, pero’, potrebbe non risultare ovvio all’utente che vede una tabella di valori. E’ possibile aggiungere un’icona indicante il concetto di dati aggiuntivi ad ognuna delle celle della nostra tabella. Per fare questo, e’ necessario modificare il metodo tableView:cellForRowAtIndexPath o aggiungere un nuovo metodo chiamato: tableView:accessoryTypeForRowWithIndexPath. In questo modo, abbiamo la possibilita’ di selezionare (tramite l’indice indexPath), le celle che hanno bisogno o meno di mostrare dati aggiuntivi.

Nota come una delle due linee di return sia commentata. Entrambe le linee sono valide, quello che cambia e’ il valore del DisclosureButton associato. A seconda di quale delle due opzioni utilizziamo, avremo un’icona o un piccolo segno di spunta ad indicare la presenza di un’ulteriore vista.
L’ultima cosa da fare e’ configurare il titolo della NavigationBar, in maniera da rispecchiare il punto di navigazione in cui ci troviamo. Per fare questo, modifichiamo il metodo loadView della UIViewController che visualizza i dettagli della nostra selezione.

Riferimenti
- iOS Developer Library: UITableView Class Reference
- iOS Developer Library: UINavigationController Class Reference
- iOS Developer Library: iOS Application Programming Guide
- iOS Developer Library: View Programming Guide for iOS
- iPhone SDK Application Development – Capitolo 3

4 Responses to “9. Objective-C: UITableView (parte 1)”
20 Dicembre 2011
CarloCiao, rinnovo i complimenti per l’utilità di questo sito.
Come già provato in passato inserire una UITableView in una UIScrollView è sempre un problema. Su un progetto per iPad non ho problemi sull’intercettazione degli eventi ma, quando scorro la tabella verso l’alto, la prima cella visibile esce dai limiti della view della tabella per poi sparire. Così anche per l’ultima cella se scorro la tabella verso il basso. Qualche suggerimento?
Grazie
21 Dicembre 2011
CarloScusate la segnalazione, ho risolto. Per un test precedente avevo applicato al layer della tabella piana il cornerRadius e il masksToBounds e non li ho poi tolti. La stanchezza ….
Ciao
22 Dicembre 2011
Downloadcell.textLabel.text = cellValue;
L’assegnazione a text è deprecata.
8 Gennaio 2012
DanieleCiao sto provando ad ottenere lo stesso risultato usando solo una tableview richiamata a sua volta da una gabbar. L’unico problema e’ che non riesco ad inserire il titolo nella barra in alto. E’ possibile? O bisogna per forza usare un navigation controller?
Grazie Daniele