Curs de programació d’iOS Novembre de 2011
Organitza
8 Llistes (UITableView i UITableViewController) • Les llistes interac/ves permeten als usuaris seleccionar, eliminar i reordenar elements. • S’empren en la gran majoria d’aplicacions. • Els elements es desplacen ver/calment tal i com ho farien amb un UIScrollView
Llistes
• Hi ha diferents /pus de llistes
Llistes • Taules planes (plain table view)
Llistes • Taula agrupada (grouped table view)
Llistes • Taula plana indexada (plain with sec4on index)
Llistes • Per treballar amb una llista cal implementar un controlador i la seva vista: • Un controlador UITableViewController • Una vista UITableView
Llistes • Un UITableView és una subclasse de UIScrollView, de la qual n’hereta la capacitat de fer scroll i l’efecte motlla “bouncy”. • La vista UITableView representa gràficament una llista. • Cada filera de la llista s’anomena cel·∙la. • Les cel·∙les són vistes del /pus UITableViewCell
Llistes • Les llistes es poden agrupar. Com a mínim tenen un grup. • Cada grup (sec4on) consta d’un conjunt de cel·∙les. • Els grups tenen una capçalera.
UITableView • Un UITableView és una vista; per tant, d’acord amb el patró Model-‐Vista-‐Controlador, només te representació visual però no es capaç de ges/onar ni la lògica ni les dades.
• UITableView necessita un delegate que implemen/ el protocol UITableViewDelegate per no/ficar de qualsevol acció sobre la vista. • UITableView necessita un delegate que implemen/ el protocol UITableViewDataSource que actui com a origen de dades.
UITableViewController • Un UITableViewController és una classe que pot dur a terme totes les funcions mencionades: • Controlador de la vista UITableView • Delegate de UITableViewDelegate • Delegate de UITableViewDataSource
UITableViewDataSource
s’ajusta a
UITableViewDelegate
s’ajusta a delegate
UITableViewController tableView
dataSource
UITableView
Exemple 8 – Catàleg simple de cotxes • CatalegTableViewController.h #import <UIKit/UIKit.h> @interface CatalegTableViewController : UItableViewController { NSMutableArray *cotxes_familiars; } -‐ (void)inicialitzarDades; @end
Exemple 8 – Catàleg simple de cotxes • CatalegTableViewController.m #import “CatalegTableViewController.h” #import “Cotxe.h” @implementa/on CatalegTableViewController -‐ (void)inicialitzarDades { cotxes_familiars = [[Cotxe obtenirCotxesFamiliars] retain]; } -‐ (void)dealloc { [cotxes_familiars release]; [super dealloc]; } @end
Exemple 8 – Catàleg simple de cotxes
Exemple 8 – Catàleg simple de cotxes
Exemple 8 – Catàleg simple de cotxes
Protocol UITableViewDataSource • Ara CatalegTableViewController emmagatzema objectes de /pus Cotxe. • Mitjançant el protocol UITableViewDataSource el UITableView solicitarà aquestes dates a mostrar. • hkp://developer.apple.com/library/IOs/ #documenta/on/UIKit/Reference/ UITableViewDataSource_Protocol/Reference/ Reference.html
Protocol UITableViewDataSource • Aquest protocol defineix un conjunt de mètodes que hem d’implementar. De tots els mètodes n’hi ha dos que s’han d’implementar obligatòriament:
-‐ (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSecOon:(NSInteger)sec4on
Retornem el número de cel·∙les de les seccions (grups) -‐ (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) indexPath
Retornem la cel·∙la que cal mostrar a una determinada filera
Protocol UITableViewDataSource • Defineix altres mètodes no menys importants. -‐ (NSInteger)numberOfSecOonsInTableView:(UITableView *)tableView
Retornem el número de seccions (grups) -‐ (NSString *)tableView:(UITableView *)tableView OtleForHeaderInSecOon:(NSInteger)sec4on
Retornem el otol de la secció especificada -‐ (NSString *)tableView:(UITableView *)tableView OtleForFooterInSecOon:(NSInteger)sec4on
Retornem el peu de la secció especificada
Exemple 8 – Catàleg simple de cotxes • CatalegTableViewController.m #import “CatalegTableViewController.h” #import “Cotxe.h” @implementa/on CatalegTableViewController -‐ (void)inicialitzarDades { cotxes_familiars = [[Cotxe obtenirCotxesFamiliars] retain]; } -‐ (void)dealloc { [cotxes_familiars release]; [super dealloc]; }
-‐ (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSec/on:(NSInteger)sec4on { return [cotxes_familiars count]; } -‐ (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSub/tle reuseIden/fier:@”UITableViewCell”] autorelease]; Cotxe *cotxe = [cotxes_familiars objectAtIndex:[indexPath row]]; [[cell textLabel] setText:[cotxe marca]]; [[cell detailTextLabel] setText:[cotxe model]]; [[cell imageView] setImage:[UIImage imageNamed:[cotxe foto]]]; return cell; } @end CatalegTableViewController tableView:numberOfRowsInSecOons
count dataSource
UITableView
cotxes_familiars
NSMutableArray
CatalegTableViewController tableView:cellForRowAtIndexPath:
objectAtIndex: dataSource cotxes_familiars
UITableView
NSMutableArray
0 UITableViewCell
0 1 2
UITableViewCell
UITableViewCell
Cotxe
1 2
Cotxe
Cotxe
UITableViewCell • Un UITableViewCell és una subclasse de UIView, i cada fila d’una vista UITableView està representada per una instància de UITableViewCell • Un UITableViewCell està compost per dos vistes: • contentView: S’hi mostren les dades. • accessoryView: S’hi mostra l’accessori.
UITableViewCell
UITableViewCell
contentView (Vista de conOnguts)
Vista dels conOnguts de la cel·∙la
accessoryView (Vista accessori)
UITableViewCell • Tipus de cel·∙les estàndar de l’SDK:
UITableViewCell • Tipus d’accessoris estàndar de l’SDK: • UITableViewCellAccessoryDisclosureIndicator • UITableViewCellAccessoryDetailDisclosureBuZon • UITableViewCellAccessoryCheckmark • UITableViewCellAccessoryNone cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
• Accessori customitzat: cell.accessoryView = [[ UIImageView alloc ] initWithImage:[UIImage imageNamed:@“imatge.png" ]];
ReuOlització de cel·∙les • L’iPhone te una quan/tat limitada de memòria. No és recomanable carregar en memòria moltes cel·∙les. • Només és necessari carregar en memòria les cel·∙les que l’usuari veu. Les que estan fora de l’àrea de visió no cal tenir-‐les en memòria i s’alliberen. • Reu/litzant dinàmicament les cel·∙les evitarem colapsar la memòria del disposi/u.
ReuOlització de cel·∙les • Quan l’usuari es mou per la llista, algunes cel·∙les surten de la pantalla i van a parar a un dipòsit (caché) de cel·∙les disponibles per a la seva reu/lització. • Enlloc de crear una nova cel·∙la cada vegada, l’origen de dades comprova en primer lloc si hi ha cel·∙les disponibles al dipòsit.
ReuOlització de cel·∙les La cel·∙la Cell 1 surt de la pantalla...
UITableViewCell 1
UITableViewCell 2
L’usuari mou la llista en aquesta direcció
UITableViewCell 3 UITableViewCell 4
...i és reintroduïda novament
UITableViewCell 1
Porció visible de l’UITableView
ReuOlització de cel·∙les
-‐ (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSub/tle reuseIden/fier:@”UITableViewCell”] autorelease]; Cotxe *cotxe = [cotxes_familiars objectAtIndex:[indexPath row]]; [[cell textLabel] setText:[cotxe marca]]; [[cell detailTextLabel] setText:[cotxe model]]; return cell; }
Subclasses de UITableViewCell • Podem implementar subclasses de UITableViewCell per dissenyar les nostres propies cel·∙les totalment a mida.
Exemple 9 – Catàleg de cotxes • CotxeTableViewCell.h #import <UIKit/UIKit.h> #import “Cotxe.h" @interface CotxeTableViewCell : UITableViewCell { UIImageView *marc_thumbnail; UIImageView *thumbnail; UIImageView *background_cella; UIImageView *puntuació; UILabel *e/queta_marca; UILabel *e/queta_model; Cotxe *cotxe; } @property (nonatomic, retain) Cotxe*cotxe; -‐ (void)esPaginador:(bool)p; @end
Exemple 9 – Catàleg de cotxes • CotxeTableViewCell.m #import “CotxeTableViewCell.h" @implementa/on CotxeTableViewCell -‐ (void)layoutSubviews { if (self.edi/ng) return; [super layoutSubviews]; CGRect contentRect = self.contentView.bounds; CGRect frame = CGRectMake(90, 5, 200, 17); self.categoria.backgroundColor = [UIColor clearColor]; self.categoria.frame = frame; //Mostrar el /tular de l'ar/cle frame = CGRectMake(90, 23, 200, 44); self./tular.backgroundColor = [UIColor clearColor]; self./tular.frame = frame; //Es fa rotar l'indicador [self startRotate];