Tip:
Highlight text to annotate it
X
Salve a tutti! In questo tutorial, realizzato con xCode 4.6 per iOS 6.1 in collaborazione con Giorgio Minissale,
vedremo come creare una UITableView con cell di tipo StyleSubtitle
e come gestire il comportamento classico di “didSelectRowAtIndexPath”.
Partiamo creando un progetto nuovo di tipo “Empty Application”, chiamandolo iBrowserTable,
e NON selezioniamo i check su ARC e Storyboard.
Di default adesso abbiamo un'app senza view iniziali, con la sola window.
Vogliamo mettere, all'inizio della nostra app, una UITableView, che conterrà le row valorizzate
con i principali siti web di nostro interesse che verranno aperti in una UIWebView.
Creiamo la TableViewController, con tasto destro sulla label del project e “New File”.
Il nuovo file sarà naturalmente una Objective-C class, chiamata “TableViewController”,
sottoclasse (subclass..) di UITableViewController.
Salviamo e ritorniamo al progetto, precisamente in AppDelegate.m, perché adesso dobbiamo dire all'app
che non deve mostrarci la Window con sfondo bianco iniziale ma la TableView.
Cominciamo aggiungendo in AppDelegate.h la @property per la TableViewController:
@property (strong, nonatomic) TableViewController *tableViewController;
Dobbiamo anche importare in AppDelegate.h il file header della classe TableViewController:
#import "TableViewController.h".
Spostiamoci in AppDelegate.m e settiamo la rootViewController con la nostra tableViewController;
per far ciò, dobbiamo prima inizializzare la tableViewController in questo modo:
self.tableViewController = [[[TableViewController alloc] initWithStyle:UITableViewStylePlain]autorelease];
Settiamo dunque la rootViewcontroller:
self.window.rootViewController = self.tableViewController;
e cancelliamo l'ormai inutile:
self.window.backgroundColor = [UIColor whiteColor];
Se siamo curiosi, e di sicuro lo siamo, vediamo che già eseguendo ora il programma (cmd + r o Run in alto a sx),
abbiamo il nostro simulatore di iPhone con una table vuota all'interno.
La tabella sarà popolata da un array “_dataTable” di dictionary inizializzato in TableViewController.m in questo modo:
@implementation TableViewController {
NSArray *_dataTable; }
Tramite l'initWithStyle della TableViewController, popoliamo quest'ultima seguendo questa procedura
che ci risulterà utile quando creeremo le row:
_dataTable = @[
@{@"url" : @"http://www.apple.com", @"title" : @"Apple", @"icon" : @"apple.png"},
@{@"url" : @"http://www.google.it", @"title" : @"Motore di ricerca - Google", @"icon" : @"google.png"},
@{@"url" : @"http://www.twitter.com", @"title" : @"Social Network - Twitter", @"icon" : @"twitter.png"},
@{@"url" : @"http://www.facebook.com", @"title" : @"Social Network - Facebook", @"icon" : @"facebook.png"}
];
Come possiamo vedere il file TableViewController.m contiene già dei metodi adatti per la creazione delle table
(lo fa in automatico Xcode quando gli diciamo la subclass, in questo caso di tipo UITableViewController).
Vediamo anche che il progetto attualmente ha due warning; il codice ci sta dicendo che i metodi:
(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
richiedono di essere configurati esplicitamente, in quanto settati di default a 0.
Il “numberOfSectionsInTableView” ritorna il numero di sezioni che avrà la tabella; per sezioni si intendono i gruppi.
Nel nostro caso ci sarà un unico gruppo, quindi settiamo il return a 1:
return 1;
e cancelliamo la riga del #warning.
Il “numberOfRowsInSection” ritorna alla table il numero di row che contiene;
in questo esempio sarà un numero fisso, ossia il “count” degli elementi presenti nell'array “_dataTable”.
Mettiamo quindi:
return [_dataTable count];
e cancelliamo il #warning.
Adesso prima di passare alla creazione di una cell custom, usiamo una delle celle di default che ci mette
a disposizione UITableViewCell, in modo da vedere subito i primi risultati di quello che abbiamo fatto fino ad ora.
Spostiamoci nel metodo
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath”
che è quello che si occupa di creare le singole row della table, e cambiamo lo style
con cui viene inizializzata la “cell”; impostiamolo a: UITableViewCellStyleSubtitle.
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]
Gli stiamo dicendo che vogliamo una cell che supporti anche la possibilità di inserire un sottotitolo.
Per configurare la cell usiamo:
cell.textLabel.text = _dataTable[indexPath.row][@"title"];
cell.detailTextLabel.text = _dataTable[indexPath.row][@"url"];
subito sotto la init della cell.
Il “cell.textLabel.text” setta il titolo della nostra cella, prendendolo dall'array “_dataTable” con indice indexPath.row
(cioè la riga che sta creando; questo indice è correlato al count degli elementi presenti nell'array _dataTable,
che gli abbiamo dato in “numberOfRowsInSection”).
Accediamo quindi al dictionary presente dentro la posizione indexPath.row,
chiamando il valore avente come chiave “title”.
Il “cell.detailTextLabel.text” ci permette di settare il sottotitolo della cella.
Riepilogando: la nostra “cellForRowAtIndexPath” attualmente è configurata come visibile a video.
Compiliamo e lanciamo il tutto sul simulatore.
Notiamo come in automatico vengano impostati il font-size, font-color e font-style tra title e subtitle.
Aggiungiamo adesso al nostro progetto le immagini relative ad ogni sito web elencato, stando attenti
a chiamarle così come definito precedentemente nel nostro array di dictionary _dataTable.
Per ordinare meglio il tutto creiamo una folder che conterrà le img.
Per creare una folder, agiamo come fatto per creare un nuovo file, ma stavolta selezioniamo “New Group”.
Chiamiamolo ad esempio “Icone” e trasciniamogli dentro le icone ricordandoci di aver messo
il giusto nome ad ognuna (per questo punto vi consiglio di fare una rapida ricerca su google
e di cercare direttamente file .png di dimensione 512x512).
Quando trasciniamo le icone png dentro il progetto, nella folder appena creata ci apparirà un messaggio di Xcode;
assicuriamoci che i check siano impostati come visibile a video, in modo che ogni file png venga copiato
all'interno del nostro progetto al target iBrowserTable.
Adesso per richiamare le img alla giusta posizione non ci resta che aggiungere questa riga di codice
sempre dentro il metodo cellForRowAtIndexPath precisamente sotto la definizione del subtitle (detailTextLabel):
cell.imageView.image = [UIImage imageNamed:_dataTable[indexPath.row][@"icon"]];
per cui stiamo dicendo alla “cell” che la sua “imageView” contiene una “image”
il cui nome è contenuto nel _dataTable, per la chiave @”icon”.
Adesso definiamo l'interazione con “ didSelectRowAtIndexPath”, cioè facciamo in modo che in caso di un “tap”
su di una row, venga visualizzata la relativa pagina web in una nuova view.
Per fare questo dobbiamo prima aggiungere un “Navigation Controller” al nostro rootViewController.
Torniamo al file AppDelegate.m e aggiungiamo questa riga di codice sotto l'init della tableViewController:
UINavigationController *navigationController = [[UINavigationController alloc]
initWithRootViewController:self.tableViewController];
e modifichiamo l'attuale rootViewController in questo modo:
self.window.rootViewController = navigationController;
Avendo aggiunto il NavigationController avremo una navBar in alto nella tableView.
Diamole un titolo: da TableViewController.m, sotto l'init dell'array _dataTable, aggiungiamo questa riga di codice:
self.title = @"Siti Preferiti";
Compilando adesso, avremo il risultato visibile a video.
Interagendo con le row, però, non avviene nulla.
Creiamo una nuova classe di tipo UIViewController, chiamata DetailViewController
e mettiamo il “Check” su “With XIB for user interface”.
Modifichiamo il nostro “DetailViewController” in modo che quando viene inizializzato
(verrà inizializzato alla pressione su una row nella table, quindi nel metodo presente in TableViewController.m
– didSelectRowAtIndexPath) riceva dal chiamante l'indirizzo web
che deve aprire ed il titolo che deve mostrare nella sua navBar.
Aggiungiamo quindi il nostro init personalizzato in DetailViewController.h:
-(id)initWithWebAddress:(NSString*)urlString andTitle:(NSString*)title;
e la sua definizione in DetailViewController.m:
-(id)initWithWebAddress:(NSString*)urlString andTitle:(NSString*)title{
if (self) {
_urlString = urlString;
self.title = title; }
return self; }
La urlString che passiamo servirà per inizializzare la _urlString interna,
mentre il title verrà impostato in alto nella view.
Rimuoviamo anche la init di default già presente nel file.
Aggiungiamo anche la definizione di _urlString e la webView, sempre in DetailViewController.m:
@implementation DetailViewController{
NSString *_urlString;
IBOutlet UIWebView *webView; }
Colleghiamo l'outlet della UIWebView nel file DetailViewController.xib dopo averla trascinata sulla view esistente.
Adesso torniamo al DetailViewController ed implementiamo nel viewDidLoad
il codice per aprire il sito web al suo interno:
-(void)viewDidLoad {
[super viewDidLoad];
NSURL *indirizzoWebUrl = [NSURL URLWithString:_urlString];
NSURLRequest *httpRequest = [NSURLRequest requestWithURL:indirizzoWebUrl];
[webView loadRequest:httpRequest]; }
Ok, questo era l'ultimo punto! Compiliamo e godiamoci il risultato visibile ora a video.
Bene, per questo tutorial è tutto; a presto!