Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 24 di 32
  • livello intermedio
Indice lezioni

L'oggetto UITableView: come mostrare i dati

Analisi dell'oggetto UITableView, l'oggetto che visualizza i dati in formato tabellare in un'applicazione iOS
Analisi dell'oggetto UITableView, l'oggetto che visualizza i dati in formato tabellare in un'applicazione iOS
Link copiato negli appunti

Iniziamo a dare forma al nostro ListViewController (che ricordiamo mostrerà i dati inseriti) inserendo un nuovo oggetto: l'UITableView. Quest'ultimo altro non è che una tabbella e risulta essere uno degli oggetti maggriormente utilizzato nello sviluppo di applicazioni iOS. Risulta anche essere uno strumento molto potente in quanto, in maniera relativamente semplice, avremo la possibilità di mostrare anche un grande numero di informazioni in maniera ordinata.

Struttura di un oggetto UITableViewCell

Ogni singola entry della tabella, che mostrerà le informazioni di un singolo elementi, è un oggetto di tipo UItableViewCell opportunamente creato. I principali attributi che sfrutteremo, appartanenti alla classe UITableViewCell, sono i seguenti:

  • textLabel: è una label nella quale inserire il contenuto principale di una cella e che nel nostro caso conterrà il valore associata alla property name dell'oggetto Fruit.
  • detailTextLabel: è una label aggiuntiva (e che avrà un font di dimensione inferiore rispetto alla precedente label) di una cella e che nel nostro caso conterrà il valore associata alla property origin dell'oggetto Fruit.
  • imageView: è un oggetto di tipo UIImageView che conterrà l'immagine della cella e che nel nostro caso sarà uguale alla property image dell'oggetto Fruit.

I contenuti all'interno di una tabella sono organizzati gerarchicamente utilizzando le sezioni e le righe. L'oggetto NSIndexPath racchiude per ogni elemento della tabella, la sua sezione e la sua riga offrendo così un indice univoco. Anche la TableView, oltre ad avere un delegate come gli oggetti UITextField e UITextView precedentemente incontrati, possiede anche un data source ovvero una classe che fornirà alla tabella i dati da impaginare; la classe data source dovrà implementare il protocollo UITableViewDataSource mettendo così a disposizione dello sviluppatore dei metodi che consentiranno il popolamento della tabella.

Implementiamo la tabella nella classe ListViewController

Fatta questa breve introduzione teorica vediamo come inserire la tabella nella nostra applicazione. Come prima cosa, dato che dobbiamo impaginare le informazioni immagazzinate in oggetti di tipo Fruit è necessario definire delle property sugli attributi della classe per concederne l'accesso. Andiamo quindi nel file Fruit.h ed inseriamo le seguenti property:

@property (nonatomic,strong) NSString* name;
@property (nonatomic,strong) NSString* origin;
@property (nonatomic,strong) NSString* description;
@property (nonatomic,strong) UIImage* image;

Spostiamoci poi nel file Fruit.m ed effettuiamo il synthesize delle property:

@synthesize name = _name;
@synthesize origin = _origin;
@synthesize description = _description;
@synthesize image = _image;

Concluse queste operazioni iniziali andiamo a dichiarare un oggetto di tipo UITableView all'interno del file ListViewController.h:

UITableView *_tableView;

Passiamo poi alla sua allocazione all'interno del metodo initWithNibName: boundle: nel seguente modo:

_tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 480) style:UITableViewStylePlain];
 _tableView.dataSource = self;
 _tableView.delegate = self;
[self.view addSubview:_tableView];

Come possiamo vedere, nell'inizializzazione della tabella, abbiamo anche definito il suo style; i due tipi di stile associabili alla tabella sono UITableViewStylePlain e UITableViewStyleGrouped (vedremo in seguito le differenze tra le rese grafiche dei due stili). Abbiamo poi scelto di associare come dataSource e come delegate la nostra stessa classe. Nel file ListViewController.h andiamo ad implementare il protocollo UITableViewDataSource e il protocollo UITableViewDelegate nel seguente modo:

@interface ListViewController : UIViewController <InsertDelegate, UITableViewDataSource,UITableViewDelegate>

Adesso abbiamo a dispozizione i metodi necessari per poter impaginare i dati all'interno della tabella. I metodi obbligatori per poter correttamente mostrare a schermo delle informazioni all'interno della tabella sono i seguenti:

  • numberOfSectionsInTableView:: è il metodo che ritorna il numero di sezioni possedute dalla tabella
  • tableView: numberOfRowsInSection:: è il metodo che, dato l'indice di una sezione, ritorna il numero di righe associate a quella sezione
  • tableView: cellForRowAtIndexPath:: è il metodo che, dato un oggetto di tipo NSIndexPath (quindi l'indice univoco per l'elemento della tabella), si occupa di mostrare i dati di un elemento.

Tali metodi verranno invocati in maniera automatica quando la tabella verrà istanziata. Andiamo adesso ad implementare tali metodi. Spostiamoci nel file ListViewController.m ed inseriamo il seguente codice:

- (int)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [_itemsList count];
}

Al primo metodo facciamo tornare valore 1 perchè vogliamo una sola sezione per la nostra tabella. Al secondo metodo facciamo tornare, come numero di righe, la lunghezza dell'array _itemsList contenente gli oggetti Fruit.h creati nella classe InsertViewController.

Adesso mostriamo il codice relativo al metodo che si occupa del popolamento dei dati all'interno della tabella:

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
    cell.textLabel.text = [[_itemsList objectAtIndex:indexPath.row]name];
    cell.detailTextLabel.text = [[_itemsList objectAtIndex:indexPath.row]origin];
    cell.imageView.image = [[_itemsList objectAtIndex:indexPath.row]image];
    return cell;
}

Prima di analizzare il codice è opportuno fare una breve panoramica sul funzionameto della creazione delle celle. Il funzionamento standard di una tabella è quello di allocare in memoria tanti oggetti UITableViewCell quante sono le celle visibili della tabella nello schermo del dispositivo. Tutte le volte che l'utente effettua uno scroll della tabella, in automatico viene richiamo il metodo tableView: cellForRowAtIndexPath: che non andrà a creare altri oggetti di tipo UITableViewCell, ma bensì utilizzerà quelli precedentemente creati andando solamente a cambiarne il contenuto.

Passando al codice, per implementare questo comportamento, definiamo un CellIdentifier di tipo NSString che verrà utilizzato per l'acquisizione della cella usando il metodo dequeueReusableCellWithIdentifier che implementerà la politica di riuso degli oggetti cella. Con quel metodo viene ritornato un oggetto di tipo UITableViewCell utilizzando il CellIdentifier precedentemente creato e se la cella risulta uguale a nil (quindi la cella non è ancora stata creata) la allochiamo e ne inseriamo il contenuto adando a reperire le informazioni all'interno dell'array _itemsList utilizzando l'indice univoco IndexPath.row (ovvero il numero di riga con valore della sezione pari ad 1).

Quando l'utente effettuerà uno scroll della tabella la cella ritornata dal meotodo dequeueReusableCellWithIdentifier sarà una cella valida e quindi il flusso d'esecuzione non entrerà all'interno del blocco condizionale if e verrà effettuato solo un aggiornamento dei contenuti.

Adesso l'infrastruttura necessaria per il corretto funzionamento della tabella è terminata. Dobbiamo però aggiungere sempre nel file ListViewController.m all'interno del metodo insertNewFruit: (dopo l'aggiunta del nuovo oggetto Fruit nell'array) la seguente linea di codice:

[_tableView reloadData];

Questa chiamata è necessaria perchè, come abbiamo detto prima, i metodi per il popolamento dei dati vengono chiamati quando la tabella viene allocata e l'array dei frutti inseriti ha lunghezza zero. E' dunque necessario, dopo ogni inserimento, invocare il metodo reloadData sulla tabella per aggiornare i dati mostrati.

Finalmente, effettaundo un Run del progetto (dopo l'inserimento di qualche frutto), avremo il seguente risultato:

tabella in iOS

Ti consigliamo anche