Rieccoci con la seconda parte del nostro tutorial. Se non avete ancora letto la prima parte su come creare una lista di preferiti, vi consiglio di farlo ora. Come promesso, in quest’ultima parte vedremo come mostrare i preferiti nella tableView che vi avevo preparato, come modificare questa lista e come far si che le righe nella tabella aprano le relative detailView. Iniziamo con la cosa fondamentale: mostrare i preferiti.
Mostrare la lista dei preferiti
Dal momento che abbiamo già tutto pronto (vedi prima parte del tutorial) non ci resta che modificare la classe che gestisce la nostra tableView dei preferiti, il file “SecondTable.m”. Per prima cosa, importiamo gli header delle classi che ci permettono di mostrare gli elementi salvati:
#import "Favorite.h"
#import "FavoritesData.h"
Inseriamo ora il nostro caro osservatore, come abbiamo fatto per salvare i preferiti:
- (void) _refreshFav {
[self.tableView reloadData];
}
// in viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_refreshFav) name:REFRESH_FAVORITES object:nil];
// in dealloc
[[NSNotificationCenter defaultCenter] removeObserver:self];
Infine, modifichiamo i metodi della tableView come segue, in modo da effettivamente mostrare i preferiti:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [[FavoritesData sharedFavoritesData] getFavorites].count;
}
- (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];
}
// Configure the cell...
Favorite *fav = (Favorite *)[[[FavoritesData sharedFavoritesData] getFavorites] objectAtIndex:indexPath.row];
cell.textLabel.text = fav.favId;
cell.detailTextLabel.text = fav.description;
// Inserisce l'immagine FullStar al lato sinistro della cella
NSString *nomeImmagine = [NSString stringWithFormat:@"FullStar.png"];
[[cell imageView] setImage:[UIImage imageNamed:nomeImmagine]];
return cell;
}
// Cell Accessory
- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellAccessoryDisclosureIndicator;
}
// CellHeight
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 50;
}
A questo punto, compilando ed eseguendo il nostro progetto dovremmo essere in grado di poter indicare un elemento come preferito e vederlo nella tableView “preferiti”. Manca solo il poter selezionare una delle righe in modo che queste aprino le relative detailView:
// importiamo l'header della prima tableView
#include "FirstTable.h"
// modifichiamo il metodo didSelectRowAtIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Favorite *fav = (Favorite *)[[[FavoritesData sharedFavoritesData] getFavorites] objectAtIndex:indexPath.row];
NSString *selectedItem = fav.favId;
if ([selectedItem isEqualToString:@"Titolo Riga 1"]) {
Detail1 *detailViewController = [[Detail1 alloc] initWithNibName:@"Detail1" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
} else if ([selectedItem isEqualToString:@"Titolo Riga 2"]) {
Detail2 *detailViewController = [[Detail2 alloc] initWithNibName:@"Detail2" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
} else {
Detail3 *detailViewController = [[Detail3 alloc] initWithNibName:@"Detail3" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
}
Notate come sia in questa classe, che in FistTable, abbia usato sempre “isEqualToString” e mai “==” per confrontare la riga e l’elenco dei preferiti/degli elementi. Questo perchè altrimenti, alla chiusura dell’applicazione l’indirizzo in memoria delle varie stringe cambia e l’eguaglianza in riapertura dell’app non è più verificata. Quando si devono confrontare delle stringe conviene sempre usare “isEqualToString”.
Modificare la tableView: modificare l’ordine delle celle ed eliminare le righe
Per concludere, rendiamo la nostra tableView modificabile:
//in viewDidLoad
self.navigationItem.rightButtonItem = self.editButtonItem;
//fuori da viewDidLoad
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
//controlla se l'azione compiuta è un'eliminazione
if (editingStyle == UITableViewCellEditingStyleDelete) {
Favorite *fav = (Favorite *)[[[FavoritesData sharedFavoritesData] getFavorites] objectAtIndex:indexPath.row];
if(fav)
{
[tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[[FavoritesData sharedFavoritesData] removeFavoriteById:fav.favId];
[tableView endUpdates];
}
}
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
[[FavoritesData sharedFavoritesData] saveFavorites];
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
Abbiamo finito. Proviamo a compilare ed eseguire la nostra applicazione e tutto dovrebbe funzionare.
Alla prossima!
Se avete problemi con il tutorial, questo è il nostro file di progetto.

25 Responses to “T#086 – Creare una lista di Preferiti (Parte 2)”
22 Febbraio 2011
Tweets that mention Creare una lista di Preferiti nelle applicazioni iPhone e iPad | devAPP -- Topsy.com[…] This post was mentioned on Twitter by iPadWorld.it, Rynox, devAPP, Bubi Devs, Vanni Giannozzi and others. Vanni Giannozzi said: T#086 – Creare una lista di Preferiti (Parte 2): Rieccoci con la seconda parte del nostro tutorial. Se non avete… http://bit.ly/hwK8i0 […]
23 Febbraio 2011
fastCiao, bel tutorial, ma se l’immagine nella tabella (la stellina) la volessi vedere sul lato destro, cosa cambia?
23 Febbraio 2011
Gianluca TranchedoneLe celle mostrano l’immagine solo a sinistra. Per mostrarla a destra dovresti cambiare la freccetta in accessoryView così:
UIImageView *favoritesStar = [[UIImageView alloc] initWithImage:[UIImage imagedNamed:@”FullStar.png”]];
cell.accessoryView = favoritesStar;
[favoritesStar release];
23 Febbraio 2011
Gianluca TranchedoneOps, qualcosa non va… ho provato ma non funziona… ho risolto però usando questo codice:
UIImage *favoritesStar = [UIImage imageNamed:@”FullStar.png”];
cell.accessoryView =[[[UIImageView alloc] initWithImage:favoritesStar] autorelease];
p.s. dimenticavo, questo va inserito in “cellForRowAtIndexPath”
23 Febbraio 2011
fastwow, grazie mille!!!
28 Febbraio 2011
AndreaE se anzichè avere 3 DetailView ne avessi una sola che cambia a seconda di quello che deve mostrare? Come posso dare i valori da inserire nella view dei preferiti? Classico esempio di un lettore di feed rss.
28 Febbraio 2011
Gianluca TranchedoneAllora dovresti modificare buona parte del codice che ho presentato nella prima parte del tutorial.
Se ad esempio le righe della tableView principale mostrassero dati provenienti da un’array i cui dati hanno alcune caratteristiche (es. nome, cognome, indirizzo) che poi richiami nella DetailView, potresti usare una di queste caratteristiche o aggiungerne una nuova da richiamare in funzioni che controllino che quell’elemento dell’array sia un preferito o meno. Nel caso di questo tutorial ho usato FAV_ID come identificativo.
4 Giugno 2011
LucaCiao, ho seguito questi tutorial e letto i commenti, ma non ho capito bene come potrei modifcare il codice nel caso io abbia, premendo una cella della tabella, un’unico detailViewController, che credo sia la situazione piu’ comune, cioe’ quando si hanno un bel po’ di dati da mostrare in tableView, caricati appunto da un array bello lungo… ho anche aperto una discussione sul forum in merito http://forum.devapp.it/showthread.php?1956-creare-una-lista-di-preferiti
5 Giugno 2011
Gianluca T.Ciao Luca. La cosa è abbastanza semplice: avrai notato che nella funzione “makeFavourite” viene usata la costante FAV_ID come identificativo dell’elemento preferito e la costante FAV_DESC come identificativo della sua descrizione. Beh invece che usare FAV_ID e FAV_DESC dovresti usare due variabili identificative diverse, relative al dato che vuoi salvare come preferito.
Ipotizziamo che tu abbia tabella contenente elementi di tipo Dato avente le proprietà “titolo” e “descrizione”. Se alla tua detailView passi un’oggetto della classe Dato per mostrarne i dettagli, qui, nella funzione “makeFavourite” userai dato.titolo al posto di FAV_ID e dato.descrizione al posto di FAV_DESC. Il risultato non cambia.
Tutto chiaro?
7 Giugno 2011
LucaSi grazie ci sono riuscito! Suggerimento impeccabile, semplice e diretto! Domanda: ma i preferiti sono eprsistenti o se spengo l’App mi vanno via??
9 Giugno 2011
Gianluca TranchedoneI preferiti sono salvati fintanto che l’app rimane installata sulla device. 😉
13 Giugno 2011
AntonioSalve io devo salvare un oggetto al posto delle 2 stringhe, ma quando l’app carica i dati mi restituisce gli oggetti tutti a null… Qualcuno può dirmi a cosa è dovuto?
14 Giugno 2011
GianlucaQuando salvi un preferito mentre usi l’app i preferiti cambiano (cioè, l’elemento viene salvato e visualizzato come preferito?) Se si, allora il problema è che stai eseguendo un paragone tra due puntatori diversi usando l’operatore ==. Risolvi facilmente il problema usando invece il metodo isEqualToClassName: (dove ClassName è il nome della classe del parametro che passi. Es. se compari due stringhe la funzione sarà [stringa isEqualToString: altraStringa].
20 Giugno 2011
LucaGrazie Gianluca ti ringrazio per la risposta sulla “persistenza” dei preferiti!! 😉
21 Giugno 2011
AlfioSAalve perchè quando aggiungo un oggetto ai preferiti, questo non viene caricato subito ma solo quando carito un altro elemento?
Cioe la table view si aggiorna ma tranne l’ultimo elemento, la cosa strana è che nel metodo cellForRowAtIndexPath l’array “cronologia” è completo di tutti gli oggetti, però ne carica uno meno (l’ultimo non lo carica). Qualcuno può aiutarmi?
7 Novembre 2011
Andrea BianchiSalve, complimenti per il bellissimo sito. Vorrei sapere se nel caso volessi passare una UIImage al posto della stringa “description” e farla apparire nei preferiti (una UImage diversa per ogni cella) cosa dovrei fare?
grazie e un saluto
3 Dicembre 2011
BySpySalve a tutti, ho notato che se in modalità “edit” sposto gli oggetti a mio piacere e dopo ne cancello uno, non cancella quello giusto ma quello che in precedenza si trovava in quella posizione.
n.b. questa cosa succede anche nell’esempio scaricato da questa pagina.
Qualche idea???
31 Dicembre 2011
GianlucaPrima di tutto scusate per il ritardo con cui rispondo ai vostri commenti! Spero che abbiate già trovato risposta alle vostre domande, ma in ogni caso (e per chi leggerà l’articolo e i commenti in futuro):
@AndreaBianchi: in questo esempio, per salvare i preferiti usiamo una NSMutableArray. Un’istanza di questa classe può contenere un qualsiasi oggetto, quindi anche immagini.
@BySpy: non avevo prestato attenzione al riordino, scusami. In ogni caso, per farlo basta riordinare gli elementi dell’array dei preferiti.
11 Gennaio 2012
byspyGianluca ma scusami di cosa??? 🙂 sei veramente bravo e molto umile.
cmq grazie della risposta, vedrò di provare il tuo suggerimento e ti faccio sapere.
23 Gennaio 2012
SergioCiao Grandissimo Gianluca,
anche io ho notato il problema evidenziato da BySpy eseguendo una cancellazione dopo un riordino…
Saresti così gentile da postare il codice modificato per evitare questo fastidioso problema?
Grazie e ancora GRANDISSIMO per l’eccezionale tutorial!
13 Febbraio 2012
BySpyCiao Gianluca, non so se hai già risolto, cmq, provo a postare come ho risolto io sperando che sia anche il “modo giusto” di farlo, perchè non sono un esperto 😉
nel file FavoritesData.h ho aggiunto:
- (void) riordinaFavoriteById:(NSInteger)fromInt:(NSInteger)toInt;
allora nel file FavoritesData.m ho aggiunto questo:
- (void) riordinaFavoriteById:(NSInteger)fromInt:(NSInteger)toInt
{
//recupero il valore della cella che sposto.
Favorite *favorite = (Favorite *)[_favArray objectAtIndex:fromInt];
//cancello la cella da dove si trova attualmente
[_favArray removeObjectAtIndex:fromInt];
// la inserisco nella posizione dove l'ho spostata
[_favArray insertObject:favorite atIndex:toInt];
//salvo
[self saveFavorites];
// e ricarico.
[[NSNotificationCenter defaultCenter] postNotificationName:REFRESH_FAVORITES object:nil];
}
Nel file SecondTable.m richiamo il codice e gli passo gli indici from e to:
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPat
{
[[FavoritesData sharedFavoritesData] riordinaFavoriteById:fromIndexPath.row :toIndexPath.row];
}
Spero che possa essere d’aiuto a qualcuno alle prime armi come me 🙂
Ciauz
16 Febbraio 2012
Sergio@BySpy
grazie davvero per il codice che hai postato…
Però visto che sono alle prime armi sicuramente più di te non capisco da dove arriva _favArray….
Mi pare che non c’era nel codice sul tutorial… bisogna sostituire con qualcosa?
Ti ringrazio!!
Sergio
16 Febbraio 2012
BySpyCiao Sergio,
_favArray è l’array che contiene l’elenco dei favoriti che poi verrà scritto su file.
la sua dichiarazione la trovi nel file FavoritesData.h mentre la sua implementazione nel file FavoritesData.m ed è proprio in questo file che viene “ordinato” secondo gli spostamenti.
oddio, se proprio non ci riesci ti zippo il tutorial con la correzione e lo pubblico.
Mi farebbe ancor più piacere se ci riuscissi da solo ok?
Ciao
29 Febbraio 2012
SergioCiao BySpy,
in effetti avevo semplicemente sbagliato a copiare il codice 🙂
Comunque grazie lo stesso perchè dopo aver visto il tuo post ho riprovato e ci sono riuscito.
Te ne sono molto grato! Davvero grazie ancora.
Ciao
Sergio
13 Marzo 2012
BySpyFigurati 🙂
Ciao