In questo nuovo tutorial di programmazione iPhone e iPad rispondiamo ad alcune richieste che arrivano dal nostro forum e nello specifico concentreremo la nostra attenzione su una particolare property presente in tutti gli oggetti dell’UIKit, il tag, ovvero un identificativo numerico che possiamo associare ad un nostro particolare oggetto. Questa proprietà, anche se sembra banale, è in realtà molto importante e ci permette di rintracciare i nostri oggetti in alcuni casi particolari. Andiamo a scoprire insieme di cosa si tratta.
Per capire il motivo dell’importanza della proprietà “tag” dobbiamo analizzare cosa succede quanto creiamo un oggetto nella nostra applicazione. Vediamo un piccolo esempio.
Per creare all’interno della nostra app un qualsiasi oggetto facente parte dell’UIKit siamo soliti utilizzare un’istruzione simile alla seguente:
UILabel * lblIp = [[UILabel alloc] initWithFrame:CGRectMake(75, 110, 150, 20)];
Così facendo non facciamo altro che definire un puntatore ad un oggetto di tipo UILabel chiamato “lblIp”. Attenzione, perchè mentre lo sviluppatore associa il nome lblIp all’oggetto, il compilatore associa “lblIp” ad un indirizzo di memoria, che di fatto andrà poi a puntare al nostro oggetto vero e proprio. A questo punto, quindi, il nostro oggetto avrà un retain uguale a 1, necessiterà di risorse (memoria) per poter essere utilizzato.
Solitamente, a questa prima riga di codice, seguono altre istruzioni in cui settiamo tutte le proprietà che ci interessano della nostra Label (nelle istruzioni di esempio che seguono settiamo solo la nuova property “tag” su cui ci stiamo focalizzando, ma è sott’inteso che potremo personalizzare tutto quanto sarà necessario):
lblIp.tag = 10;
Ora che abbiamo il nostro oggetto personalizzato, ci interesserà sicuramente aggiungerlo ad una view all’interno della nostra applicazione, per farlo scriveremo:
[view addSubview:lblIp];
Fermiamoci un attimo e vediamo cosa è successo a questo punto. Il nostro oggetto è stato aggiunto alla nostra vista “view”, il suo retain vale ora 2 e, se vogliamo che la vita del nostro oggetto, la label, sia gestita da ora in avanti dalla vista, dovremo rilasciarlo tramite la seguente istruzione:
[lblIp release];
Ecco che il retain della nostra label torna a 1 (grazie al rilascio) ma cosa più importante, oltre ad aver aggiunto il nostro oggetto alla view, con il rilascio abbiamo definitivamente perso il puntatore all’oggetto.
Ma se abbiamo perso questo importante riferimento, come possiamo usare ora la nostra label nel resto del programma?
Grazie proprio alla property tag!
Il tag, come accennato ad inizio articolo, non è nient’altro che un identificativo numerico che assoceremo ai nostri oggetti. Questo identificativo dovrà essere un numero intero maggiore o uguale a zero e il suo scopo è proprio quello di recuperare un oggetto non avendo più a disposizione il suo puntatore.
Ecco spiegato come la proprietà tag possa tornarci utile, è evidente la sua importanza, non credete?
E’ chiaro che se abbiamo creato e personalizzato un oggetto è nostro interesse utilizzarlo nel programma che stiamo realizzando. Per recuperare la label dell’esempio quindi, dopo averne fatto il release, dovremo scrivere:
UILabel * lblTemp = (UILabel*)[view viewWithTag:10];
Naturalmente dobbiamo far capire al programma che l’oggetto che stiamo recuperando è di tipo UILabel e quindi facciamo il casting alla view che viene ritornata dal metodo [viewWithTag:10].
Questa operazione è possibile con tutti gli oggetti che fanno parte del framework UIKit, perché ereditano tutti da UIView.
Esempio pratico
Detto questo passiamo ad un esempio più pratico. Supponiamo di avere una UITableView e che in ogni cella vogliamo inserire un bottone custom. Ecco sorgere il primo problema: come possiamo capire poi, durante l’utilizzo, a quale bottone corrisponde l’evento che abbiamo aggiunto?
La risposta è semplicissima, usiamo i tag!
Vediamo come. Creiamo un nuovo progetto di tipo “Navigation-based”, arriveremò così direttamente al sodo senza perderci in troppe chiacchiere e avremo a disposizione una bella tableView già pronta su cui lavorare.
Modifichiamo quindi il codice come segue:
File RootViewController.h
@interface RootViewController : UITableViewController
{
NSArray * arraySource;
}
-(void)showTagButton:(id)sender;
@end
Abbiamo aggiunto un semplice array che ci servirà per inserire alcuni elementi nella nostra tabella, e il metodo che verrà richiamato al tap su du un bottone (che aggiungeremo a breve nelle celle).
Il sender è molto importante perché ci permette di recuperare l’oggetto a cui è stato aggiunto l’evento, da quest’oggetto recuperiamo il tag e così facendo abbiamo l’elemento esatto del nostro array (più difficile dirlo a parole che a farlo via codice:))
Passiamo al file di implementazione “RootViewController.m” e modifichiamolo come segue:
- (void)viewDidLoad
{
[super viewDidLoad];
arraySource = [[NSArray alloc] initWithObjects:@"primo",@"secondo",@"terzo",@"quarto",@"quinto", nil];
}
Qui non abbiamo fatto altro che allocare “arraySource” (il nostro array) e inizializzarlo con cinque stringhe di esempio.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [arraySource count];
}
Settiamo il numero di righe per sezione (nel nostro esempio abbiamo una sola sezione) e finalmente creiamo la nostra cella personalizzata, quella che conterrà i vari button:
- (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] autorelease];
//Creiamo il nostro UIButton
UIButton * btnShow = [UIButton buttonWithType:UIButtonTypeCustom];
//Lo personalizziamo
[btnShow setBackgroundImage:[UIImage imageNamed:@"btnAdd.png"] forState:UIControlStateNormal];
[btnShow setTitle:@"tag" forState:UIControlStateNormal];
[btnShow setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
btnShow.frame = CGRectMake(200, 10, 70, 30);
//Impostiamo la property tag di ogni button in modo che sia uguale all'indice della riga dove risiede ogni bottone
btnShow.tag = indexPath.row;
[btnShow addTarget:self action:@selector(showTagButton:) forControlEvents:UIControlEventTouchDown];
[cell.contentView addSubview:btnShow];
}
// Configure the cell.
cell.textLabel.text = [arraySource objectAtIndex:indexPath.row];
return cell;
}
La prima modifica che facciamo è quella di cambiare il tipo di cella in UITableViewCellStyleSubtitle poi sempre dentro l’if creiamo il nostro bottone. Ricordiamoci la parte più importante, quella del tag. In questo caso non occorre rilasciare in quanto i button sono stati creati tramite “buttonWithType”, anzichè tramite il metodo “alloc/init”, sono quindi in autorelease e non siamo noi responsabili della loro gestione (se avete dubbi in merito, andate a rispolverare qualche articolo sulla gestione della memoria sulle nostre pagine).
Fatto questo impostiamo il titolo alla cella con la stringa presa dall’arraySource.
A questo punto non ci rimane che implementare il metodo showTagButton:
-(void)showTagButton:(id)sender
{
UIButton * btnTemp = (UIButton*)sender;
int row = btnTemp.tag;
NSString * rowString = [NSString stringWithFormat:@"tag: %i",row];
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:[arraySource objectAtIndex:row]
message:rowString
delegate:self cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
;
;
}
Nella prima riga otteniamo il bottone dal sender, facendo un semplice cast, dal bottone otteniamo il tag che coincide con la riga impostata precedentemente e a questo punto visualizziamo una semplice UIAlertView.
Come vedete niente di complicato, con un piccolo esempio abbiamo visto come si utilizzano i tag e a cosa servono!
Per qualsiasi dubbio o riflessione in merito ci trovate sul Forum, dove sicuramente qualcuno (me compreso) vi può dare una mano.;)
Buon lavoro!
Andrea Cappellotto
Se avete problemi con il progetto presentato, questo è il link per scaricare il nostro esempio.
4 Responses to “T#099 – Scopriamo la property TAG e impariamo ad usarla durante lo sviluppo di Applicazioni iOS”
2 Agosto 2011
ignaziocOttimo articolo, vorrei precisare solo una cosa…il puntatore all’oggetto non lo si perde per aver fatto il release ma solo quando esce dallo scope.
2 Agosto 2011
Andrea Cappellottogiustissimo… qualcosa mi sfugge sempre.. per questo avevo aizzato quella famosa richiesta…;)
8 Agosto 2011
MauroSalve ragazzi, compliementi per il sito e per i tutorial, grazie a voi ho imparato molto sulla programmazione Mac ^^.. vorrei chiedervi cosa usate per la scrittura del codice nell’articolo, quello che somiglia a pastebin, perchè mi servirebbe una cosa simile per il mio sito fatto però in joomla.
Grazie Mille!
5 Settembre 2011
ikarowebOttimo articolo del mio amico Andrea! 😉