Sei sulla pagina 1di 85

TUTO RIAL PRATICI PER IPHONE SDK

Andrea Busi, BubiDevs

www.bubidevs.net

Prima Edizione - Giugno 2009

Guida pratica a#iPhone SDK

INDICE
Prefazione Capitolo 1: Introduzione al SDK e ad XCode
Introduzione Panoramica sul SDK XCode

5 6
6 6 7

Capitolo 2: Come creare un nuovo progetto


I template di XCode Creare un nuovo progetto Interface Builder

9
9 11 11

Capitolo 3: Il nostro primo progetto, He#oWorld!


Creiamo la struttura graca Deniamo gli elementi e le azioni Scriviamo il codice necessario Facciamo nascondere la tastiera

14
14 15 18 19

Capitolo 4: TrashApp, gestiamo le immagini


Deniamo lapplicazione Deniamo gli o%etti e la classe Implementiamo il movimento del logo Il ripristino del logo

21
21 24 26 28

Capitolo 5: UIToolbar e auto-rotazione


Creiamo la struttura graca
Guida pratica a#iPhone SDK

29
29
2

Deniamo la classe e gli o%etti Scriviamo il codice necessario

32 33

Capitolo: 6: NSTimer e UIProgressView


Creiamo la struttura graca Deniamo la classe e gli o%etti Scriviamo il codice

35
35 36 38

Capitolo 7: AccessContact, accediamo a#a rubrica


Deniamo il progetto Deniamo la struttura graca Scriviamo il codice necessario

41
41 42 43

Capitolo 8: Creiamo un mini browser con le UIWebView


Creiamo la struttura graca Deniamo i componenti e co#eghiamo le azioni Scriviamo il codice per aprire la pagina desiderata

46
46 47 49

Capitolo 9: UITableView, gestiamo le tabe#e


Parte 1: creiamo e deniamo la tabe#a Creiamo un nuovo progetto Deniamo la struttura graca Inseriamo il codice necessario Parte 2: Inseriamo alcune funzionalit A%iungiamo la barra di navigazione Permettiamo la cance#azione di una riga

51
51 51 52 53 56 56 57

Guida pratica a#iPhone SDK

Rendiamo le ce#e selezionabili Parte 3: Implementiamo la ricerca A%iungiamo il box di ricerca Modichiamo i metodi gi esistenti Implementiamo la ricerca

58 60 60 61 63

Capitolo 10: XML


Cosa XML? XML nel SDK di iPhone Creiamo la struttura graca Scriviamo il codice necessario

66
66 68 68 70

Capitolo 11: Gestire pi viste create con IB


Creiamo la vista principale Creiamo la vista (e la classe) VistaUno Facciamo caricare la prima vista a#avvio de#applicazione Creiamo la vista (e la classe) VistaDue Impostiamo le azioni per muoverci tra le viste

74
74 75 78 81 82

Guida pratica a#iPhone SDK

Prefazione
Questo libro racchiude tutti i tutorial che ho creato sulla programmazione per iPhone e iPod Touch. Non vuole essere un manuale esauriente o sostituirsi alla documentazione uciale Apple, ma solo uno strumento per chi alle prime armi, oppure per chi vuole imparare qualcosa che ancora non sa. Troverete una serie di guide pratiche, da seguire passo per passo, commentate e spiegate, per consentire a tutti di imparare e capire quello che viene fatto. Ringrazio chiunque legga queste pagine, sperando di potervi aiutare in un vostro scopo, sia lavorativo o per pura passione (come la mia). Ringrazio Fabiano Confuorto, fondatore e amministratore di iSpazio, una stupenda community che mi ha fatto scoprire il mondo iPhone, e che mi ha dato lopportunit di creare e pubblicare i miei primi tutorial. Ringrazio la mia danzata, che mi ha sempre sopportato e supportato, seppur non sappia niente di programmazione! Ringrazio Steve Jobs, per aver creato Mac e liPhone, cercando sempre la perfezione nelle cose. E ricordatevi, solo essendo curiosi e aamati possibile scoprire e creare qualcosa di nuovo e veramente innovativo. Siate aamati, siate fo#i.

Guida pratica a#iPhone SDK

Capitolo 1: Introduzione al SDK e ad XCode


I NTRODUZIONE
Con il rilascio del rmware 2.0, Apple ha segnato una svolta nel settore mobile: non era mai stato cos semplice sviluppare e vendere le proprie applicazioni. Per permettere tutto ci, Apple ha creato AppStore, uno spazio che si integra al gi famoso e collaudato iTunes Store. Qualsiasi sviluppatore, indipendente o azienda gi aermata, pu pubblicare le proprie creazioni semplicemente acquistando una licenza annua, al prezzo di 99$ (79 per noi europei). Ma come si sviluppano le applicazioni? Il tutto davvero molto semplice (in pieno stile Apple): insieme al rmware 2.0, infatti, stato rilasciato un SDK (Software Development Kit) uciale, che integra tutti gli strumenti necessari per creare applicazioni e giochi per iPhone e iPod Touch. Questo SDK liberamente scaricabile dalliPhone Dev Center (http://developer.apple.com/iphone/), previa registrazione gratuita (ma si pu accedere alla sezione anche con il proprio account di iTunes). L iPhone Dev Center larea di Apple dedicata agli sviluppatori (ovviamente di applicazioni per iPhone), in cui si pu trovare davvero tantissimo materiale molto utile: esempi con codice ben commentato, documentazione delle librerie, documenti teorici, video, e molto altro ancora. Come ho gi detto, per pubblicare applicazioni in AppStore necessario disporre della licenza uciale. Questo, per, non basta per vedere pubblicate le proprie creazioni: ogni applicazione, infatti, passa sotto il controllo di Apple, che decide se accettarle o meno. Le applicazioni presenti in AppStore, infatti, devono rispettare il contratto del SDK, che prevede alcune limitazioni: vietato, ad esempio, duplicare funzioni gi presenti nel S.O. delliPhone (come linvio di SMS e MMS), oppure sono vietate applicazioni con contenuto a sfondo sessuale o violento. Non pensate, quindi, di poter fregare Apple: c chi si visto riutare la propria applicazione anche per una semplice icona.

P ANORAMICA SUL SDK


Dopo aver scaricato e installato lSDK (unimmagine dmg di circa 2 GByte), troverete tutto il necessario per sviluppare nella cartella /Developer/Applications. Gli strumenti (davvero molto potenti) che Apple mette a disposizione sono i seguenti: Dashcode, un utile tool con cui potremo creare pagine web, widget (anche per la Dashboard di Mac OS X) e altro; Instruments, permette di analizzare e valutare le prestazioni delle nostre applicazioni (in termini di consumo di memoria, impiego del processore, etc). destinato, ovviamente, agli sviluppatori pi esperti. Interface Builder, grazie a questa applicazione sar davvero un gioco da ragazzi creare laspetto graco dei nostri programmi. Potremo inserire qualsiasi tipo di oggetto (bottoni, label, viste) semplicemente trascinando gli oggetti nella nostra schermata.

Guida pratica a#iPhone SDK

Quartz Composer, un tool che permette di creare animazioni ed eetti graci, da utilizzare poi in altri programmi. XCode, lambiente di sviluppo vero e proprio. Sar qui, infatti, che andremo a creare i nostri progetti, scrivere il codice e compilare il tutto. lo strumento, insieme ad Interface Builder, che utilizzeremo di pi.

XC ODE
Analizziamo, ora, come si presenta XCode. Aprendo un progetto (vedremo nel capitolo 2 come crearne un nuovo) otterremo la seguente schermata:

Potete notare tre sezioni principali: a destra troviamo Groups & Files, in cui abbiamo tutti i le che compongono il nostro progetto. Troveremo, quindi, le classi, le immagini inserite, i framework utilizzati. A destra, invece, possiamo vedere leditor del codice, che ci assister e ci permetter di scrivere il nostro codice. La barra in alto, inne, ci ore la possibilit di compilare ed installare la nostra applicazione, sul dispositivo che preferiamo: il nostro iPhone (solo nel caso in cui abbiamo la licenza uciale) oppure liPhone Simulator (un simulatore che ci per-

Guida pratica a#iPhone SDK

metter di testare le nostre applicazioni comodamente sul Mac, senza dover installare nulla sul nostro iPhone). Particolare importanza ha il men a tendina presente a sinistra della barra. Se lo apriamo troviamo le seguenti voci:

Nella prima parte, denominata Active SDK andremo a selezionare la versione del rmware con cui vogliamo che sia compatibile la nostra applicazione. Questo necessario in quanto spesso, con il rilascio di nuovi rmware, vengono aggiunte anche nuove funzioni al SDK (le API). Quindi, unapplicazione scritta e compilata per il rmware 2.2 potrebbe non funzionare con una versione inferiore del rmware (spesso proprio impossibile installarla, in quanto lAppStore controlla questa compatibilit in fase di installazione). Al contrario, se compiliamo lapplicazione per la versione 2.1 funzioner sicuramente (a meno che non utilizziate delle API con dei bug) sulla 2.2. importante, quindi, scegliere con cura la versione da utilizzare, per non escludere parte di utenza dallutilizzo della nostra applicazione. possibile, inoltre, scegliere se eseguirla sul simulatore (e in tal caso ci basta scegliere quelle con presso Simulator) oppure sul nostro iPhone. La seconda impostazione molto importante riguarda Active Conguration: selezionando lopzione Debug otterremo unapplicazione pi pesante, progettata per essere testata e corretta (proprio in quella che viene denita fase di debug); la versione Release, invece, molto pi leggere ed pronta per essere rilasciata e pubblicata in AppStore.

Guida pratica a#iPhone SDK

Capitolo 2: Come creare un nuovo progetto


Abbiamo dato unocchiata al SDK e ad XCode. venuto il momento di iniziare a vedere gli strumenti che XCode ci mette a disposizione per realizzare i nostri progetti. In questo capitolo vedremo come creare un nuovo progetto, quali template XCode ci mette a disposizione e le caratteristiche principali di Interface Builder.

I TEMPLATE

DI

XC ODE

Avviando XCode e selezionando File -> New Project..., si aprir la seguente nestra:

Potete notare che XCode ci fornisce vari template, ovvero delle strutture gi pronte, che ci permetteranno di realizzare applicazioni sullo stile di quelle native. Non dovremo perdere tempo, quindi, per replicare lo stile delle altre applicazioni, perch Apple stessa che ce li mette a disposizione.

Guida pratica a#iPhone SDK

Navigation-Based

Tab Bar Application

Utility Application

Analizziamo, ora, i vari template che ci vengono forniti. Navigation-Based Application, genera unapplicazione in cui possiamo navigare in sotto-livelli. Per farvi un esempio, pensate alla struttura di Impostazioni nel vostro iPhone: avete una barra in alto che visualizza il titolo della sezione corrente, e vi permette, tramite un bottone, di tornare alla sezione precedente. Questa barra viene chiamata Navigation Bar. Utile per creare applicazioni con tabelle, in cui vogliamo mostrare anche le informazioni sui vari elementi. OpenGL ES Application, questa sicuramente la tipologia pi complessa, in quanto si basa sulla tecnologia OpenGL (http://it.wikipedia.org/wiki/OpenGL), sfruttata principalmente per realizzare videogiochi o animazioni grache complesse. In questo libro non analizzeremo questa tipologia di applicazioni. Tab Bar Application, fornisce unapplicazione con la tab bar, ovvero la barra nera composta da pi sezioni (ad esempio quella che trovate nellapplicazione nativa Musica). Utility Application, questa tipologia implementa un men che viene richiamato ruotando la schermata principale. Anche in questo caso, potete trovare una similitudine con lapplicazione Meteo: se premete sulla i presente a fondo pagina, la schermata ruoter e vi permetter di modicare i settaggi dellapplicazione. View-Based Application, fornisce unapplicazione vuota, senza nessuna implementazione particolare. Questo template composto da una nestra, chiamata MainWindow, e una vista, [nome_progetto]ViewController, che viene caricata proprio dalla nestra principale. Sar questo punto di partenza per tutti i nostri tutorial. Window-Based Application, molto simile al caso precedente, ma il template fornito composto solamente da una nestra (non presente quindi la vista [nome_progetto]ViewController).

Guida pratica a#iPhone SDK

10

C REARE

UN NUOVO PROGET TO

In ogni tutorial che vedremo, sar necessario creare un nuovo progetto. Per fare ci, vi baster aprire XCode, selezionare File -> New Project..., si aprir la nestra con la scelta del template, che abbiamo appena analizzato. Scegliete il template desiderato (generalmente sar ViewBased Application), cliccate su Choose.. e nel box successivo inserite il nome del nostro progetto. Finito!

I NTERFACE B UILDER
Scorrendo la sezione Groups & Files possiamo vedere tutti i le che XCode ha gi inserito per noi. Nel capitolo 3 vedremo come creare la nostra prima applicazione (il classico HelloWorld), ora ci limitiamo ad analizzare le caratteristiche principali dellInterface Builder. Facciamo doppio clic su [nome_progetto]ViewController.xib, nella cartella Resources, e si aprir Interface Builder. Ci ritroveremo con una situazione simile a questa:

Potete notare vari strumenti sul vostro desktop: la libreria, la schermata della nostra applicazione (per ora completamente grigia), ed altri strumenti. Analizziamo ora questi componenti.

Guida pratica a#iPhone SDK

11

Library, la libreria da cui possiamo inserire tutti gli oggetti che desideriamo. Se non gi aperta, ci baster andare in Tools -> Library e si aprir una nestra come quella a lato. Scorrendo la barra laterale, potete notare moltissimi componenti, come bottoni, label di testo, viste, barre e molto altro. Tutti questi elementi potranno essere utilizzati nelle nostre applicazioni. Per inserirli basta trascinare un componente nella schermata dellapplicazione, e posizionarlo a proprio piacere (questo vero per tutti i componenti tranne i Controllers, che potrete riconoscere perch hanno uno sfondo giallo).

Vista o nestra, la nostra vista, ovvero la nestra che verr visualizzata sulliPhone. Potremo personalizzarla a nostro piacimento, e impareremo nei capitoli successivi come fare. L unica cosa che vi faccio notare, la freccia presente a destra del nome della vista:

Se provate a cliccarla, noterete che la vista ruota: questo perch sar possibile implementare la possibilit di ruotare la nostra applicazione quando lutente ruota il proprio iPhone. Vedremo in dettaglio questo aspetto in un tutorial successivo. Panne#o documenti, questo pannello vi mostra tutti i componenti del vostro le xib. Allinizio vi potr sembrareinutile, per quando lapplicazione inizier a diventare complessa, vi sar molto utile per ritrovare tutti i componenti della vostra nestra.

Guida pratica a#iPhone SDK

12

Inspector, sicuramente la parte pi importante di Interface Builder, in quanto ci permette di impostare qualsiasi propriet, relativa ad ogni oggetto (dalla vista al singolo bottone). Potremo, quindi, modicare laspetto degli oggetti, collegare le azioni, modicarne la dimensioni. Insomma, potrete agire su moltissimi aspetti (il tutto senza scrivere una riga di codice). L Inspector composto da 5 parti: Attributes, qui possiamo variare gli attributi generici dei nostri oggetti, ad esempio il colore, la dimensione del font, ed altre propriet che impareremo poco alla volta. Connections, uno dei pannelli principali. Qui andremo a collegare le azioni agli oggetti. Cosa signica? Ve lo spiego con un esempio. Supponiamo di avere un bottone nella nostra vista, e vogliamo che quando viene premuto venga scritto Ciao in una casella di testo. Creeremo, quindi, unazione, che si occuper di scrivere Ciao. Dovremo, poi, collegare questa azione al bottone, in modo che quando lutente preme il bottone, viene eseguito il comportamento desiderato. Vedrete che con i prossimi tutoria tutto questo sar pi familiare. Size, questa sezione permette, come dice la parola stessa, di modicare le dimensioni delloggetto, e di modicarne anche la posizione e lancoraggio (ovvero dove deve essere ssato, questo sar fondamentale quando implementeremo la rotazione della schermata). Identity, in questo pannello potremo denire la classe, gli oggetti e le azioni che ci servono, senza scrivere una riga di codice! Potremo fare tutto in maniera davvero molto semplice, e ci baster un clic per salvare la classe che avremo creato e le azioni relative. Abbiamo cos completato la panoramica sullInterface Builder. Mi pare inutile, per ora, dilungarmi in altri aspetti, che vi saranno sicuramente pi chiari e familiari con un po di pratica. In pochissimo tempo, non riuscirete pi a fare a meno di Interface Builder!

Guida pratica a#iPhone SDK

13

Capitolo 3: Il nostro primo progetto, HelloWorld!


In questo capitolo realizzeremo la nostra prima applicazione, il classico HelloWorld! Chiederemo allutente il proprio nome (ad esempio Tizio) e alla pressione di un bottone faremo apparire il messaggio Ciao Tizio. Niente di complicato quindi, per cercate di capire bene tutti i passaggi, in modo da non avere lacune su queste cose basilari.

C REIAMO

LA STRUT TURA GRAFICA

Iniziamo quindi creando un nuovo progetto di tipo View-Based Application e chiamiamolo HelloWorld. Apriamo quindi il le HelloWorldViewController.xib, che avvier anche lInterface Builder. Ora dobbiamo creare la struttura graca, che deve essere simile a questa:

Come potete osservare, ci sono tre componenti principali: 1.una UITextField in cui lutente potr inserire il proprio nome; 2.una UIButton, con la scritta Saluta!, che lutente dovr premere per far apparire il saluto; 3.due UILabel, una con la scritta Nome (e questa serve solo per rendere pi intuitivo il nostro programma), laltra posta a centro schermo (che contiene la stringa Label). importante impostare le dimensioni di questa ultima label in modo che occupi tutta la larghezza

Guida pratica a#iPhone SDK

14

della vista, altrimenti avremo problemi quando andremo a stampare il messaggio di saluto in seguito. Tramite Attribute Inspector possiamo denire alcune propriet per questi oggetti. Selezioniamo ad esempio la UITextField, e impostiamo i seguenti valori: Capitalize: Words (ovvero quando lutente inizia a digitare il proprio nome la prima lettera viene scritta in maiuscolo); Corrections: No (disabilitiamo la correzione automatica per questo campo); Spuntiamo lopzione Clear Context Before Drawing (canceller il contenuto gi presente non appena lutente seleziona il campo). A vostro piacere potete anche impostare altre propriet, provatene alcune per prendere un po pi di condenza. Prima di proseguire, diamo unocchiata a ci che compone questo le (lo potete trovare nel pannello dei documenti):

Potete notare tre elementi, che XCode ha gi denito per noi. Files Owner, come dice la parola stessa, il proprietario del le. , in sostanza, la classe che gestisce la nostra nestra, ovvero che gestisce ogni singolo aspetto. Nel nostro caso sar la classe HelloWorldViewController, dove poi andremo a scrivere il codice necessario. First Responder, per ora non un componente che ci interessa, per sappiate che si occupa, ad esempio, della gestione del multi-touch. View, la nostra vista, ovvero la schermata che abbiamo denito. In questo caso ne abbiamo solo una, ma nulla ci vieta di denirne svariate e richiamarle poi a nostro piacimento.

D EFINIAMO

GLI ELEMENTI E LE AZIONI

Dobbiamo ora denire gli elementi e le azioni necessarie. Potremmo fare questa operazione da Interface Builder (e impareremo a farlo dal prossimo tutorial), ma per questa volta lo faremo

Guida pratica a#iPhone SDK

15

via codice, in modo che capiate bene come XCode lavora. Salviamo tutto e chiudiamo Interface Builder, tornando cos in XCode. Nella cartella Classes noteremo quattro le: due con estensione .h e due con estensione .m. I le .h stanno ad indicare le classi di intestazione, ovvero dove vengono deniti i metodi e i componenti necessari, ma non vi alcuna implementazione dei metodi. Saranno i le con estensione .m a contenere tutte le implementazioni dei metodi, ovvero il codice delle varie funzioni. Iniziamo, quindi, aprendo il le He#oWorldContro#er.h, in cui dovremo denire gli oggetti che ci serviranno. Nel nostro esempio, saranno due gli elementi da denire: la UITextField in cui lutente inserisce il proprio nome (e da cui noi dobbiamo leggerne il valore), e la UILabel in cui scriveremo il saluto. Dovremo, poi, denire unazione, quella che verr richiamata alla pressione del bottone. Ecco il codice da inserire:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #import <UIKit/UIKit.h> @interface HelloWorldViewController : UIViewController { IBOutlet UITextField *fieldNome; IBOutlet UILabel *labelSaluto; } -(IBAction)saluta; @property (nonatomic, retain) IBOutlet UITextField *fieldNome; @property (nonatomic, retain) IBOutlet UILabel *labelSaluto; @end

Abbiamo dichiarato una UITextField e una UILabel, proprio i due componenti che ci servono. Possiamo notare che entrambe le dichiarazioni sono precedute dalla clausola IBOutlet, che indica ad XCode che quellelemento stato denito in Interface Builder. Questo necessario perch, come vedrete fra poco, ci permetter di collegare loggetto creato tramite Interface Builder con quello dichiarato in XCode. Dopo queste due dichiarazioni, trovate lintestazione del metodo saluta, e anche in questo caso trovate una clausola IBAction: anche questa sta a signicare che lazione collegata ad un componente di Interface Builder. Le due property, poi, servono per poter utilizzare senza problemi le propriet degli oggetti che abbiamo denito. Ora salviamo il le (Cmd + S) e riapriamo HelloWorldViewController.xib. Dobbiamo collegare questi componenti con quelli eettivamente inseriti nella nostra vista.

Guida pratica a#iPhone SDK

16

Dal pannello dei documenti selezionate il componente Files Owner. Aprendo il Connections Inspector dovreste vedere un pannello come questo:

Potete notare che sono presenti i componenti che abbiamo denito via codice! Ora non dobbiamo fare altro che collegarli agli elementi adeguati. Prendiamo il pallino a anco di eldNome e trasciniamolo no alla UITextField della nostra vista. Avremo cos collegato i due elementi! Ripetiamo la stessa operazione con labelSaluto, trascinando il pallino sulla UILabel posta a centro schermo. Stessa operazione va eseguita per lazione saluta. Collegatela al bottone, ma quando rilasciate il bottone del mouse vi apparir un men come quello che trovate qui a anco. Sono tutte le azioni che pu gestire un bottone. Noi selezioniamo Touch Up Inside, in modo che lazione venga richiamata non appena si clicca sul bottone. Volendo potremmo scegliere di avviare lazione quando il bottone viene rilasciato, ma per il nostro scopo non cambia niente. Se avete eseguito tutto correttamente avrete un pannello Connections Inspector come questo:

Guida pratica a#iPhone SDK

17

Abbiamo cos concluso la denizione dei componenti della nostra applicazione. Salviamo tutto e chiudiamo Interface Builder.

S CRIVIAMO

IL CODICE NECE SSARIO

Dobbiamo ora implementare il metodo saluta, che si occuper di leggere il nome inserito dallutente e stampare il messaggio di benvenuto sulla label predisposta. Apriamo il le HelloWorldViewController.m e inseriamo il seguente codice:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #import "HelloWorldViewController.h" @implementation HelloWorldViewController // importiamo i componenti di cui abbiamo definito le property @synthesize fieldNome, labelSaluto; // azione richiamata alla pressione del bottone -(IBAction)saluta{ // leggiamo la stringa contenuta nella TextField (il nome dell'utente) NSString *nome = fieldNome.text; if ([nome length] == 0){ // l'utente non ha inserito nessun nome labelSaluto.text = [[NSString alloc] initWithFormat:@"Ciao anonimo!"]; }else{ // salutiamo l'utente labelSaluto.text = [[NSString alloc] initWithFormat:@"Ciao %@",nome]; } } - (void)dealloc { [labelSaluto dealloc]; [fieldNome dealloc]; [super dealloc]; }

Analizziamo il codice poco alla volta. L istruzione presente alla riga 3 che ha il compito di caricare gli elementi di cui prima abbiamo denito le property. Potrebbe sembrare un po strana, ma per ora prendetela come regola. Dalla riga 9 alla 20 troviamo la denizione del metodo saluta. In tale metodo, non facciamo altro che leggere il nome inserito dallutente (tramite fieldNome.text, che ci restituisce la stringa contenuta nella UITextField) e assegnarlo alla variabile nome (riga 11). Tramite una costrutto if (dalla riga 13 alla 19) andiamo poi a controllare se tale stringa vuota (e quindi

Guida pratica a#iPhone SDK

18

lutente ha premuto il tasto senza inserire nessun nome) oppure se vi un valore. Ovviamente inseriamo due messaggi di saluto diversi a seconda del caso. Particolare attenzione merita parte dellistruzione alla riga 18, ed in particolare questo pezzo di codice: @"Ciao %@",nome. @, la prima chiocciola sta ad indicare che ci che segue una stringa. La sintassi sempre la stessa, pu essere schematizzata nel seguente modo: @stringa_desiderata. Dovrete sempre utilizzare questo formato quando istanziate una stringa. %@, quando trovate un % in una stringa, signica che li ci andr il valore di una determinata variabile. Non a caso dopo la stringa trovare la variabile nome: il contenuto di tale variabile nome andr inserito al posto di %@. Se avessimo dovuto inserire il valore di una variabile di tipo oat avremmo usato la sintassi %f. Vedremo parecchi esempi nei prossimi tutorial. Il metodo dealloc, inne, quello che si occupa di liberare la memoria che abbiamo utilizzato. L Objective-C, infatti, non prevede un gestore della memoria come avviene invece in Java (tramite il Garbage Collector). Sar compito degli sviluppatori, quindi, liberare la memoria dagli oggetti che non servono pi. In questo metodo dovrete sempre inserire i componenti che avete utilizzati, richiamando per ognuno il metodo dealloc. Nellesempio potete vedere che liberiamo dalla memoria gli oggetti labelSaluto e eldNome. Possiamo ora cliccare su Build and Go!, se non abbiamo commesso errori nellinserire il codice si avvier liPhone Simulator e potremo testare il nostro programma!

F ACCIAMO

NASCONDERE LA TASTIERA

Se provate ad inserire un nome e a premere il tasto Invio della tastiera che appare sulliPhone, noterete che essa non si chiude. Si tratta di un bug? La risposta no. normale, in quanto non abbiamo implementato niente che chiuda tale tastiera. Per sistemare questo problema, apriamo il le HelloWorldViewController.h e modichiamo lintestazione nella seguente maniera:
1 @interface HelloWorldViewController : UIViewController <UITextFieldDelega2 te>

Potete notare che abbiamo aggiunto <UITextFieldDelegate>, ovvero la nostra classe deve implementare il delegato della classe UITextField. Parleremo pi avanti di cosa siano i delegati, per ora sappiate che sono dei comportamenti comuni a delle classi di oggetti. Fatto ci, andiamo nel le HelloWorldViewController.m e inseriamo, in un qualsiasi punto, questo metodo:
1 2 3 4 -(BOOL)textFieldShouldReturn:(UITextField *)textField{ [textField resignFirstResponder]; return YES; }

Guida pratica a#iPhone SDK

19

Questo metodo si occuper della chiusura della nostra tastiera. Non soermiamoci sul codice, in quanto cos in qualsiasi occasione voi vogliate implementarlo. Salvate entrambi i le e aprite HelloWorldViewController.xib. Cliccate sulla UITextField e aprite il Connections Inspector: vedrete nella sezione Outlets un elemento chiamato delegate, prendete il pallino e trascinatelo sul Files Owner nel pannello dei documenti. Se avrete eseguito correttamente questa operazione il vostro pannello sar come questo:

In pratica, abbiamo detto che il delegato di tale oggetto gestito dalla classe HelloWorldViewController. Salvate ora il tutto e chiudete Interface Builder. Provate poi ad eseguire la vostra applicazione, tutto funzioner in maniera corretta! Avete cos creato la vostra prima applicazione funzionante per iPhone!

Guida pratica a#iPhone SDK

20

Capitolo 4: TrashApp, gestiamo le immagini


In questo secondo tutorial, inizieremo a prendere condenza con un aspetto molto importante: la gestione delle immagini, e come lutente pu interagire con esse. Andremo a creare, infatti, un nto cestino, in cui potremo trascinare unimmagine e ripristinarla tramite un apposito pulsante.

D EFINIAMO L APPLICAZIONE
Creiamo un nuovo progetto di tipo Window-Based Application e chiamiamolo TrashApp. A dierenza del tutorial precedente, questa volta creeremo tutto tramite Interface Builder, metodo sicuramente pi veloce e comodo per applicazioni non troppo complesse. Prima di fare qualsiasi cosa, inseriamo nel nostro progetto le immagini che ci serviranno. Io utilizzer le seguenti immagini: due per il cestino, e una per il documento da eliminare (potete trovare queste immagini nel le di progetto dellesempio):

TrashIconEmpty.png

TrashIconFu#.png

windows icon.png

Trascinate le immagini nel progetto in XCode, e nel pop-up che vi apparir mettere la spunta a Copy items into destination groups folder (if needed). Noterete ora le immagini allinterno del progetto:

Procediamo, quindi, con la denizione della struttura graca della nostra applicazione. Fate doppio clic sul le MainWindow.xib, si avvier Interface Builder. Dalla Library prendete un componente UIView e trascinatelo nella nestra principale della vostra applicazione. Dovreste avere una schermata come questa:

Guida pratica a#iPhone SDK

21

Inseriamo, poi, gli altri elementi necessari: due componenti UIImageView e un UIButton. Attenzione: la prima UIImageView che inserire deve essere quella in basso, altrimenti avrete problemi nelle fasi successive! Ecco come si presenter la vostra applicazione:

Guida pratica a#iPhone SDK

22

Ora dobbiamo collegare i vari componenti alle immagini che abbiamo inserito allinizio nel progetto. Clicchiamo sul primo componente UIImageView (quello pi in alto, ma il secondo che avete inserito!) e apriamo il pannello Attributes Inspector. Nel men a tendina Images selezioniamo il le windows icon.png e lo vedremo comparire anche nellapplicazione. Spuntiamo, inoltre, la casella User Interaction Enabled. Avremo un pannello cos impostato:

Facciamo la stessa cosa per la UIImageView sottostante, selezionando come immagine TrashIconEmpty.png, ma senza spuntare User Interaction Enabled. Inseriamo allinterno del bottone la scritta Ripristina, aggiustiamo le dimensioni e la posizione delle due immagini (in modo che i bordi delle UIImageView coincidano con le immagini al loro interno) no ad avere un risultato come questo:

Guida pratica a#iPhone SDK

23

D EFINIAMO

GLI OGGET TI E LA CLASSE

Una volta impostata la struttura graca della nostra applicazione, dobbiamo denire gli oggetti e le azioni necessarie. Se vi ricordare, nello scorso tutorial abbiamo fatto tutto via codice, e poi abbiamo collegato gli oggetti da Interface Builder. Ora, invece, eseguiremo tutto direttamente da Interface Builder, da cui creeremo anche la classe necessaria. Clicchiamo sullo sfondo della nostra vista ed entriamo nel pannello View Identity. Nel campo Class scrivete MainView (questo sar il nome della nostra classe), nella sezione Class Outlets fate due clic sul pulsante + per aggiungere due elementi. Il primo rinominatelo in imageLogo, il secondo in imageCestino, e in entrambi inserite UIImageView come tipo. Cliccate, poi, sul + della sezione Class Actions, rinominando il nuovo elemento in ripristina:. Dovreste avere, quindi, una schermata come questa:

Ora dobbiamo connettere gli elementi e lazione che abbiamo appena denito. Questo lo faremo come abbiamo gi imparato(e andr fatto sempre cos). Apriamo, quindi, la scheda Connections Inspector, vedremo i due elementi (imageLogo e imageCestino) che abbiamo appena creato. Prendiamo il pallino che troviamo a anco di imageLogo e trasciniamolo sul logo di Windows, mentre quello di imageCestino sullimmagine del cestino. Colleghiamo, inne, lazione: proprio come nello scorso tutorial, colleghiamo il pallino dellazione ripristina: sul bottone, e nel men che appare selezioniamo Touch Up Inside. Se abbiamo eseguito tutto in maniera corretta avremo un pannello come il seguente:

Guida pratica a#iPhone SDK

24

L ultima cosa che ci resta da fare creare la nostra classe (che si chiamer MainView, ovvero il nome che abbiamo inserito in precedenza). Dal men File clicchiamo Write Class Files..., si aprir una nestra in cui dobbiamo selezionare la cartella di destinazione. Selezioniamo la cartella Classes e clicchiamo poi su Save.

Nella schermata che apparir subito dopo mettiamo la spunta sul nostro progetto TrashApp e poi clicchiamo Add.

Guida pratica a#iPhone SDK

25

Abbiamo creato cos la nostra classe, che ritroveremo poi in XCode! Salviamo tutto e chiudiamo Interface Builder.

I MPLEMENTIAMO

IL MOVIMENTO DEL LOGO

In XCode possiamo notare che vi sono due nuovi le: MainView.h e MainView.m. Iniziamo completando la denizione della classe MainView. Apriamo, quindi, il le MainView.h e scriviamo il seguente codice:
1 2 3 4 5 6 7 8 9 10 11 12 13 #import <UIKit/UIKit.h> #import <Foundation/Foundation.h> @interface MainView : UIView { IBOutlet UIImageView *imageCestino; IBOutlet UIImageView *imageLogo; BOOL cancellato; } - (IBAction)ripristina:(id)sender; - (void)cancella; @end

Per prima cosa abbiamo denito la superclasse della nostra MainView: questo stato fatto alla riga numero 4, scrivendo UIView. Cosa vuol dire? Signica che la nostra classe glia di UIView, da cui erediter metodi e propriet. Questa una caratteristica della programmazione ad oggetti, che non voglio approfondire in questo libro. Alla riga 7 abbiamo aggiunto una variabile che ci servir per controllare se il nostro oggetto gi stato eliminato (quindi, al valore YES corrisponder il logo eliminato, con NO il nostro lo-

Guida pratica a#iPhone SDK

26

go sar ancora visibile); lo stesso vale per il metodo cancella, che si occuper per dellanimazione legata alleliminazione del logo. Ora iniziamo ad implementare i metodi necessari. Apriamo il le MainView.m e inseriamo i l seguente codice:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [[event allTouches] anyObject]; if ([touch view] == imageLogo) { imageLogo.center = [touch locationInView:self]; } } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { if (CGRectContainsRect([imageCestino frame], [imageLogo frame])){ imageCestino.image = [UIImage imageNamed:@"TrashIconFull.png"]; [self cancella]; } } - (void)cancella{ cancellato = YES; [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:0.5]; imageLogo.transform = CGAffineTransformMakeScale(.001, .001); [UIView commitAnimations]; }

Abbiamo denito tre metodi, che si occuperanno del movimento del logo di Windows e della sua cancellazione. vediamoli nel dettaglio: touchesMoved, (dalla riga 1 alla 6) In questo metodo, salviamo nella variabile touch levento che lutente compie toccando un qualsiasi oggetto della nostra applicazione (riga 2). Controlliamo, poi, che loggetto toccato corrisponda a imageLogo (riga 3), cio al logo di Windows: se loggetto proprio quello, teniamo traccia del centro delloggetto (che nel frattempo viene mosso dallutente) con la posizione del dito sullo schermo (riga 4). Ovvero, come se spostassimo sicamente loggetto con il nostro dito e lo muovessimo su un piano. touchesEnded, (dalla riga 8 alla 13) In questo metodo diciamo semplicemente che se il frame di imageLogo (ovvero il logo di Windows) contenuto in quello del cestino (riga 9), deve essere chiamato il metodo cancella, che si occuper dellanimazione della cancellazione (riga 11). Prima di chiamare tale metodo, inoltre, cambiamo limmagine del cestino vuoto con quella del cestino pieno (riga 10). cancella, (dalla riga 15 alla 21) In questo metodo deniamo lanimazione che avr il logo di Windows quando verr sposato sopra il cestino. Alla riga 16 cambiamo il valore della variabile cancella, in modo da sapere che il logo stato eliminato. Alla riga 17 deniamo il

Guida pratica a#iPhone SDK

27

punto di partenza della nostra animazione, mentre con listruzione successiva ne deniamo la durata. La riga 19 lanimazione vera e propria, che far scomparire il logo. Con lultima istruzione deniamo la ne dellanimazione.

IL

RIPRISTINO DEL LOGO

Abbiamo quasi terminato la nostra applicazione, manca solo la denizione dellazione ripristina:. Tale metodo gi stato denito da Interface Builder, quindi noi dobbiamo solo scrivere il codice al suo interno. Ecco le istruzioni da inserire:
1 2 3 4 5 6 7 8 9 10 - (IBAction)ripristina:(id)sender { if (cancellato) { [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:0.5]; imageLogo.transform = CGAffineTransformIdentity; imageCestino.image = [UIImage imageNamed:@"TrashIconEmpty.png"]; imageLogo.center = CGPointMake(155.0, 100.0); [UIView commitAnimations]; } }

Questo metodo speculare a cancella, in quanto dobbiamo eseguire lanimazione inversa! Andremo, quindi, ad eseguire unanimazione, che porter il logo dal cestino (in cui si trova) alla posizione originale (o quasi, in quanto denita in modo arbitrario da noi, alla riga 7). Clicchiamo ora su Build and Go!, e testiamo la nostra applicazione funzionante!

Guida pratica a#iPhone SDK

28

Capitolo 5: UIToolbar e auto-rotazione


In questo terzo tutorial, analizzeremo un componente molto importante, la UIToolbar, e una funzionalit molto gradita agli utenti, lauto-rotazione. Non creeremo nessun applicazione complicata, semplicemente avremo due pulsanti nella toolbar che modicheranno il valore di una label posta al centro dello schermo. L auto-rotazione, inne, aggiunger un tocco pi professionale alla nostra applicazione.

C REIAMO

LA STRUT TURA GRAFICA

Come sempre, la prima cosa che faremo denire un nuovo progetto. Creiamo un nuovo progetto di tipo View-Based Application e chiamiamolo CountRotateApp. Il procedimento sar molto simile a quello dello scorso tutorial, con una piccola dierenza. Noterete che ora i le .xib sono due: MainWindow.xib e CountRotateAppViewController.xib. Eliminate il secondo le, (tasto destro -> Delete e cliccando poi su Also Move to Trash). Abbiamo eliminato questo le in quanto non ci servir. Avremmo potuto utilizzarlo e sviluppare li la nostra applicazione, ma ho preferito optare per la soluzione che analizzeremo fra poco. Possiamo ora aprire il le MainWindow.xib. Avrete una nestra che si presenter come questa:

Guida pratica a#iPhone SDK

29

Apriamo lAttribute Inspector ti tale finestra, ed eliminiamo la voce CountRotateAppViewController che troviamo nel campo NIB Name:

Prendiamo ora un componente di tipo UIView dalla libreria e inseriamolo nella nostra nestra. Nella parte bassa della vista inserite una UIToolbar, con due UIBarButtonItem: in uno scrivete -, nellaltro +. Noterete che i due bottoni sono quasi attaccati. Noi vogliamo che siano ai due estremi, quindi tra di essi inseriamo un Flexible Space Bar Button Item, in modo che restino sempre separati. Ecco come si presenter la vostra toolbar:

Questo spazio essibile ha una grossa utilit: non solo ci separa i due bottoni, ma ci permette di non doverci occupare della giusta distanza tra essi, anche nel caso che ne aggiungessimo un terzo. Inoltre esso ci permette di tenere i due bottoni alle estremit della barra anche nel caso in cui ruotassimo la nostra applicazione. Come facciamo a testarlo? Semplice. Cliccate sulla freccia presente nel titolo della nestra della nostra applicazione:

Vedrete che la schermata ruoter!

Guida pratica a#iPhone SDK

30

E come possiamo notare i due bottoni restano agli estremi della nostra barra. Proprio il risultato che volevamo. Riportiamo la nestra alla sua posizione originale, e inseriamo al centro una UILabel, partendo da un angolo in alto a sinistra, per poi ingrandirla no allangolo opposto. In Attribute Inspector settate i seguenti parametri: Text: 0 (zero); A#ineamento centrale; Font Size: 200 Dovreste avere il seguente risultato:

Guida pratica a#iPhone SDK

31

Proviamo ora a far ruotare la schermata come abbiamo fatto poco fa. Noteremo che lo zero non rimane in posizione centrale, ma addirittura viene per met nascosto. Come facciamo a lasciarlo centrato? Anche qui ci viene in aiuto lInterface Builder, che ore grandi potenzialit anche in questo aspetto. Selezioniamo la label che contiene lo zero e apriamo il Size Inspector. Nella seconda parte possiamo vedere che vi una sezione denominata Autosizing. Clicchiamo sulle due freccette rosse che vediamo nel riquadro piccolo, in modo da avere questo schema:

Proviamo ora a ruotare la nostra applicazione: lo zero rester perfettamente in posizione centrale!

D EFINIAMO

LA CLASSE E GLI OGGET TI

Abbiamo imparato nello scorso capitolo come denire gli oggetti e le azioni direttamente in Interface Builder, quindi ora faremo lo stesso procedimento. Selezioniamo la vista (state attenti a selezionare correttamente il componente UIView) e apriamo lIdentity Inspector. Impostiamo come nome della classe MainView e deniamo i seguenti elementi:

Abbiamo cos denito due azioni (una per aggiungere e una per sottrarre) e un componente per la label contenente il numero. Andiamo ad eseguire i soliti collegamenti, collegando lazione

Guida pratica a#iPhone SDK

32

aggiungi: al bottone +, mentre sottrai: andr collegata con il bottone -. L elemento labelNumero, ovviamente, va associata alla label presente a centro schermo. Ecco come apparir il pannello Connections Inspector:

Dobbiamo inne creare la classe. Andiamo in File -> Write Classes Files... e salvate la classe MainView (fate riferimento al capitolo precedente se non vi ricordate il procedimento). Salvate tutto e chiudere pure Interface Builder.

S CRIVIAMO

IL CODICE NECE SSARIO

Come al solito, dobbiamo ora implementare i metodi necessari (che vedrete essere davvero semplici). Iniziamo aprendo il le MainView.h e completando lintestazione della classe nel seguente modo:
1 @interface MainView : UIView { 2 IBOutlet UILabel *labelNumero; 3 int numero; 4 }

Dovremo solamente aggiungere UIView allintestazione, e denire una variabile intera chiamata numero (che conterr il valore visualizzato nella label). Possiamo passare subito ai metodi contenuti nella classe MainView.m. Il primo metodo da aggiungere (che incontrerete molte volte nei prossimi tutorial) il seguente:
1 - (void)awakeFromNib{ 2 numero = 0; 3 }

Questo metodo viene richiamato sempre allavvio del le .xib associato alla classe (i le .xib sono quelli creati da InterfaceBuilder). In questo metodo possiamo inizializzare tutti i componenti che ci serviranno. Qui, in pratica, dobbiamo inserire tutte quelle operazioni che vogliamo vengano eseguite allavvio dellapplicazione. Nel nostro esempio, vogliamo che la variabile numero sia impostata a zero.

Guida pratica a#iPhone SDK

33

1 2 3 4 5 6 7 8 9

- (IBAction)aggiungi:(id)sender { numero++; labelNumero.text = [[NSString alloc] initWithFormat:@"%i",numero]; } - (IBAction)sottrai:(id)sender { numero--; labelNumero.text = [[NSString alloc] initWithFormat:@"%i",numero]; }

Quello che vedete qui sopra il codice che dovete inserire nei due metodi che trovate gi deniti. Non eseguono niente di complicato: prima viene incrementata (o decrementata) la variabile numero, poi viene visualizzata nella label. Semplice vero? L u l t i m a c o s a d a i m p l e m e n t a r e l a r o t a z i o n e d e l l a v i s t a . A p r i t e i l f i l e CountRotateAppViewController.m e inserite il seguente metodo (dovrebbe essere gi presente, vi baster decommentarlo e modicare unistruzione):
1 - (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation{ 2 return YES; 3 }

Questo un metodo della classe UIViewController, che implementa gi la rotazione automatica dello schermo. Ancora una volta non dovremo fare veramente niente, in quanto sono le librerie del SDK a fornirci tutti pronto. Piccola nota: se non volessimo implementare lauto-rotazione, ci basterebbe ritornare come valore NO, oppure semplicemente non inserire il metodo nellapplicazione. Clicchiamo ora su Build and Go! e testiamo la nostra applicazione!

Guida pratica a#iPhone SDK

34

Capitolo: 6: NSTimer e UIProgressView


Proseguiamo la panoramica sui componenti pi utilizzati nella creazione di applicazioni per iPhone. In questo capitolo vedremo come utilizzare la classe NSTimer, ovvero un temporizzatore, che ci permetter di eseguire animazioni e transizioni con durate predenite. Utilizzeremo, inoltre, la UIProgressView, ovvero la barra di progresso, necessaria quando si deve mostrare un caricamento. Quella che andremo a creare sar una semplice applicazione, che permetter allutente di cambiare il colore dello sfondo, semplicemente cliccando su un bottone. Il cambio del colore, inoltre, avverr in maniera graduale tramite unanimazione della durata di 10 secondi.

C REIAMO

LA STRUT TURA GRAFICA

Come sempre, iniziamo creando un progetto di tipo Window-Based Application e chiamiamolo ProgressColour. Fate doppio clic sul le MainWindow.xib per aprire Interface Builder, in cui deniremo la struttura graca dellapplicazione. Come al solito, inseriamo un componente UIView nella nostra nestra. Inseriamo, poi, gli altri due componenti necessari: una UILabel e una UIProgressView. Ricreate una disposizione simile a questa (ovviamente nessuno vi vieta di personalizzarla a vostro piacimento):

Come potete notare la label e la barra di progresso occupano quasi per intero la larghezza della vista, questo per rendere pi evidente ci che avviene. Selezioniamo la label e apriamo Attributes Inspector, per modicare alcune propriet: cancellate il contenuto del campo testo;

Guida pratica a#iPhone SDK

35

Font Size: 20 allineamento centrale. Selezioniamo ora la UIProgressView e, sempre in Attributes Inspector, impostiamo il valore della casella Progress a zero. Inseriamo ora nella vista due bottoni, in modo da avere un risultato nale come questo:

D EFINIAMO

LA CLASSE E GLI OGGET TI

Dobbiamo denire, come al solito, gli oggetti necessari e la classe. Iniziamo cliccando sulla vista e inserendo come nome MainView (ovviamente nel solito pannello Identity Inspector). Deniamo due oggetti: progressLabel (di tipo UILabel) e progressBar (di tipo UIProgressView). Fatto ci, inseriamo anche due azioni: caricamentoBlu e caricamentoRosso. Ecco come si presenter il vostro pannello alla ne di queste denizioni:

Guida pratica a#iPhone SDK

36

Sapete gi cosa dobbiamo fare ora: collegare gli oggetti e le azioni che abbiamo appena denito con i componenti graci. Apriamo quindi il Connections Inspector e colleghiamo progressBar con la UIProgressView e progressLabel con la UILabel. Colleghiamo, poi, le due azioni: caricamentoBlu con il bottone con la scritta Applica colore blu, mentre lazione caricamentoRosso con laltro bottone (quando vi appare il men con le varie azioni selezionate come sempre Touch Up Inside). Ecco come si deve presentare il vostro pannello Connections Inspector:

Salviamo ora la classe (File -> Write Class Files...) e inseriamola nel nostro progetto. Salviamo e chiudiamo Interface Builder.

Guida pratica a#iPhone SDK

37

S CRIVIAMO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

IL CODICE

Apriamo il le MainView.h e inseriamo il seguente codice:


#import <UIKit/UIKit.h> #import <Foundation/Foundation.h> @interface MainView : UIView { IBOutlet UIProgressView *progressBar; IBOutlet UILabel *progressLabel; NSTimer *timer; } @property (nonatomic, retain) NSTimer *timer; (IBAction)caricamentoBlu; (IBAction)caricamentoRosso; (void)aggiornaBlu; (void)aggiornaRosso; (void)applicaBlu; (void)applicaRosso;

@end

Abbiamo denito un componente NSTimer, che sar il temporizzatore che ci permetter di eseguire lanimazione prevista. Abbiamo denito, inoltre, quattro nuovi metodi, che ci serviranno per implementare tutte le azioni necessarie. Passiamo ora al le MainView.m e iniziamo ad implementare i metodi necessari. Inseriamo il seguente codice:
1 2 3 4 5 6 7 8 9 10 11 12 @synthesize timer; - (IBAction)caricamentoBlu { progressBar.progress = 0.0; progressLabel.text = @"Caricamento colore..."; timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(aggiornaBlu) userInfo:nil repeats:YES]; }

- (IBAction)caricamentoRosso { progressBar.progress = 0.0; progressLabel.text = @"Caricamento colore..."; timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(aggiornaRosso) userInfo:nil repeats:YES]; 13 }

Guida pratica a#iPhone SDK

38

Questi due metodi sono praticamente identici, quindi mi limiter a commentare solamente il primo. Alla riga 4 viene settato il valore di progresso della barra a zero (tale valore di default va da 0.0 a 1.0, ma questo intervallo pu essere modicato a piacere). Nella riga 5 inseriamo un messaggio nella label, in modo da comunicare allutente ci che sta avvenendo. L istruzione presente alla riga 6, inne, quella che merita pi attenzione. Viene denita la variabile timer, istanziandola con la classe NSTimer. Ci sono tre parametri molto importanti in questa funzione: la durata di 1 secondo (alla clausola scheduledTimerWithTimeInterval), il metodo che deve essere eseguito ad ogni ripetizione (clausola @selector()) e la ripetizione continua di tale intervallo di tempo (impostata tramite repeats:YES). Proseguiamo con la denizione dei metodi:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 - (void)aggiornaBlu{ progressBar.progress = progressBar.progress + 0.1; if (progressBar.progress == 0.5){ progressLabel.text = @"Applicando colore..."; [self applicaBlu]; } if (progressBar.progress == 1.0){ progressLabel.text = @"Colore applicato!"; [timer invalidate]; } } - (void)aggiornaRosso{ progressBar.progress = progressBar.progress + 0.1; if (progressBar.progress == 0.5){ progressLabel.text = @"Applicando colore..."; [self applicaRosso]; } if (progressBar.progress == 1.0){ progressLabel.text = @"Colore applicato!"; [timer invalidate]; } }

Anche questi due metodi sono praticamente uguali. Alla riga 2 incrementiamo il valore della nostra barra di progresso, aumentandone il valore del 10%. Alla riga 3 troviamo un controllo if, che verica se il valore della barra 0.5 (ovvero siamo a met): in caso aermativo, cambiamo il testo presente nella label, altrimenti lasciamo tutto invariato. Anche alla riga 7 un ciclo if controlla se la barra di progresso arrivata al suo valore massimo: in tal caso inseriamo un nuovo testo nella label, e fermiamo il timer (con listruzione alla riga 9). Nel primo ciclo if che abbiamo esaminato, notiamo che alla riga 5 viene richiamato il metodo

Guida pratica a#iPhone SDK

39

applicaBlu: tale metodo avr il compito di cambiare il colore allo sfondo della vista, con unanimazione che dovr durare 5 secondi (infatti siamo al 50% del progresso, e la barra avanza del 10% ogni secondo). Ecco i due metodi che si occupano di fare ci:
1 2 3 4 5 6 7 8 9 10 11 12 13 - (void)applicaBlu{ [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:5.0]; self.backgroundColor = [UIColor blueColor]; [UIView commitAnimations]; } - (void)applicaRosso{ [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:5.0]; self.backgroundColor = [UIColor redColor]; [UIView commitAnimations]; }

In questi due metodi viene denita lanimazione che permette allo sfondo della nostra vista di cambiare colore. L animazione rispecchia molto quella illustrata in un capitolo precedente. Alla riga 3 deniamo la durata di tale animazione (5 secondi); listruzione successiva il risultato che vogliamo ottenere, ovvero il nostro colore di sfondo. Chiude il gruppo di istruzioni la riga 5, che avvia lanimazione. Clicchiamo su Build and Go! e testiamo la nostra applicazione!

Guida pratica a#iPhone SDK

40

Capitolo 7: AccessContact, accediamo alla rubrica


In questo capitolo andremo ad implementare una funzione un po particolare, in quanto accederemo allapplicazione nativa Contatti e ricaveremo le informazioni di un contatto. Impareremo ad utilizzare il framework (una sorta di libreria, che ci fornisce delle funzionalit gi pronte) AddressBook e come sfruttare le funzioni che ci mette a disposizione.

D EFINIAMO

IL PROGET TO

Iniziamo creando un progetto del tipo View-Based Application e chiamiamolo AccessContact. Questa volta procederemo come nel primo tutorial, ovvero andremo a denire prima i componenti via codice, poi li collegheremo tramite Interface Builder. Apriamo il le AccessContactViewController,m, che la classe della vista che ci viene fornita con questo template. Inseriamo il seguente codice:
1 2 3 4 5 6 7 8 9 10 11 12 13 #import <UIKit/UIKit.h> #import <AddressBook/AddressBook.h> #import <AddressBookUI/AddressBookUI.h> @interface AccessContactViewController : UIViewController { IBOutlet UILabel *labelNome; IBOutlet UILabel *labelCognome; IBOutlet UILabel *labelTel; } - (IBAction)getContatto; @end

Ormai siete esperti, e avrete subito capito che abbiamo denito tre label e unazione. Alle righe 2 e 3, per, abbiamo importato due librerie, che si riferiscono ad AddressBook, ovvero allapplicazione Contatti. Questo, per, non basta per poter utilizzare tutte le sue funzioni. Dobbiamo importare allinterno del nostro progetto anche il framework necessario. Espandete la sezione Targets nel progetto, e cliccate con il tasto destro su AccessContact, selezionando poi Get Info. Si aprir una nuova schermata, in cui dobbiamo andare nella sezione General. Nellangolo in basso a sinistra noteremo un bottone +, clicchiamo e si aprir un elenco di tutti i framework disponibili:

Guida pratica a#iPhone SDK

41

Selezioniamo AddressBook.framework e AddressBookUI.framework e clicchiamo poi su Add. Avremo cos aggiunto questi due framework al nostro progetto. Possiamo cos chiudere la schermata delle propriet. S a l v i a m o i l f i l e Ac ce s s C o n t a c t Vi e w C o n t r o l l e r. h e f a c c i a m o d o p p i o c l i c s u AccessContactViewControlle.xib per aprire Interface Builder.

D EFINIAMO

LA STRUT TURA GRAFICA

Dobbiamo ora denire laspetto graco della nostra applicazione. Inseriamo le label necessarie e un bottone, per ricreare un aspetto graco come questo:

Guida pratica a#iPhone SDK

42

Le label con il testo --- sono quelle che poi conterranno le informazioni sul contatto selezionato dallutente. Dobbiamo ora collegare gli elementi deniti in precedenza con quelli che abbiamo appena inserito nella vista. Tramite il pannello dei documenti selezioniamo Files Owner, e apriamo il Connections Inspector. Potremo vedere i componenti che abbiamo dichiarato:

Ora dobbiamo collegarli nella maniera corretta, ovviamente in base al nome con cui li abbiamo chiamati: labelNome, quindi, andr collegata con la label a anco di Nome e cos via. L azione getContatto, invece, sar da collegare al bottone, scegliendo come sempre Touch Up Inside tra le azioni disponibili. Ecco il risultato nale dei collegamenti:

Possiamo salvare tutto e chiudere Interface Builder.

S CRIVIAMO

IL CODICE NECE SSARIO

Dobbiamo ora implementare i metodi necessari per far funzionare lapplicazione. Iniziamo con la denizione del metodo getContatto, ovvero lazione collegata alla pressione del bottone. Apriamo il le AccessContactViewController.m e inseriamo il seguente codice:

Guida pratica a#iPhone SDK

43

-(IBAction)getContatto { //Crea loggetto necessario ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init]; 4 //Il delegato delloggetto definito nella classe stessa 5 picker.peoplePickerDelegate = self; 6 //Visualizza lapp Contatti 7 [self presentModalViewController:picker animated:YES]; 8 //Rilascia loggetto 9 [picker release]; 10 }

1 2 3

Come si pu leggere dai commenti, questo metodo istanzia un oggetto chiamato picker, che ci permetter di aprire lapplicazione nativa Contatti. Alla riga 5 deniamo il delegato di tale oggetto: impostando self, comunichiamo che sar la stessa classe (ovvero AccessContactViewController) a denire gli altri metodi necessari, che deniremo tra poco. Alla riga 7, inne, inseriamo tale oggetto come vista principale della nostra applicazione: lutente vedr cos comparire lapplicazione nativa Contatti allinterno della nostra applicazione AccessContact. Dobbiamo ora implementare i metodi richiesti dal delegato. Ecco il codice da inserire:
- (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person { 2 //Settiamo il nome 3 labelNome.text = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty); 4 //Settiamo il cognome 5 labelCognome.text = (NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty); 6 //Settiamo il numero di telefono 7 ABMultiValueRef multi = ABRecordCopyValue(person, kABPersonPhoneProperty); 8 labelTel.text = (NSString*)ABMultiValueCopyValueAtIndex(multi, 0); 9 //Rimuove il controller "Contatti" 10 [self dismissModalViewControllerAnimated:YES]; 11 return NO; 12 } 13 14 15 (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationCo ntroller *)peoplePicker { 16 // facciamo tornare il controller alla vista principale 17 [self dismissModalViewControllerAnimated:YES]; 18 } 1

Il primo metodo legge le informazioni del contatto selezionato, e le setta nelle apposite label. L unico inconveniente dato dalle righe 7 e 8, che si occupano della lettura del numero di tele-

Guida pratica a#iPhone SDK

44

fono: viene letto il primo numero presente (in quanto potrebbero anche esserci pi numeri). E se non vi fosse nessun numero associato al contatto? In tal caso lapplicazione crasha. Questo avviene perch non abbiamo eettuato nessun controllo, ma potete semplicemente risolvere questo problema tramite un opportuno ciclo if. Il metodo che inizia alla riga 15, inne, si occupa di chiudere lapplicazione Contatti quando lutente sceglie di uscire senza selezionare nessun contatto (ovvero quando clicca su Cancel). Potete notare che listruzione di tale metodo uguale a quella presente alla riga 10, che uguale a sua volta a quella presente alla riga 7 del primo metodo implementato. Cliccate su Build and Go! e testate la vostra applicazione!

Guida pratica a#iPhone SDK

45

Capitolo 8: Creiamo un mini browser con le UIWebView


Una delle caratteristiche principali delliPhone la sua connettivit, sia essa tramite WiFi, 3G o EDGE. Internet, quindi, ricopre un ruolo fondamentale nellutilizzo di questo dispositivo. Ecco che sorge spesso necessario implementare una sorta di browser nelle nostre applicazioni, per poter visualizzare delle pagine web. Anche in questo lSDK si rivela molto potente, in quanto ci mette a disposizione un componente praticamente gi pronto: le UIWebView. Questo componente una sorta di Safari lite, in quanto ci permette di visualizzare pagine web tramite lo stesso motore che alla base di Safari. Nel tutorial vedremo come utilizzare le UIWebView, per realizzare un nostro mini-browser, con tre semplici pulsanti: avanti, indietro e ricarica. Certo, non potremo competere con Safari, ma potrebbe tornarvi molto utile nei vostri programmi.

C REIAMO

LA STRUT TURA GRAFICA

Iniziamo creando un nuovo progetto di tipo Window-Based Application e chiamiamolo MyBrowser. Apriamo il le MainWindow.xib per avviare Interface Builder. La prima cosa da fare inserire una UIView, che sar, come sempre, la base della nostra nestra. Inseriamo nella parte bassa della vista un componente di tipo UIToolbar e inseriamoci tre bottoni (UIBarButtonItem, quelli utilizzati nel capitolo 5), separando gli ultimi due tramite un Flexible Space (anche questo gi visto). I primi due bottoni ci serviranno per muoverci tra le pagine visitate (i classici Avanti e Indietro), mentre il terzo servir a ricaricare la pagina. Ecco come appare la barra appena denita:

Ora dobbiamo inserire la WebView. Dalla libreria scegliamo un componente UiWebView e inseriamolo nella nostra nestra. Ecco il risultato nale:

Guida pratica a#iPhone SDK

46

D EFINIAMO

I COMP ONENTI E COLLEGHIAMO LE AZIONI

Abbiamo gi concluso con la denizione dellinterfaccia graca. Dobbiamo ora denire i componenti che ci serviranno e collegare le relative azioni. Vedrete che si riveler tutto molto semplice, in quanto troveremo gi tutto pronto. Dal pannello dei documenti espandiamo il componente Window e selezioniamo la UIView (ovvero al vista che abbiamo inserito inizialmente):

Dopo aver selezionato la vista, apriamo lIdentity Inspector e inseriamo come nome della classe MainView. Inseriamo poi un oggetto webView di tipo UIWebView, avendo cos un risultato come questo:

Guida pratica a#iPhone SDK

47

Abbiamo cos denito lunico componente necessario. Andiamo poi in Connections Inspector e colleghiamo loggetto webView con la UIWebView che abbiamo inserito nella nostra applicazione. Ecco il risultato nale:

Possiamo salvare la classe creata, tramite il men File -> Write Class Files... e inserirla nel nostro progetto. Non chiudiamo Interface Builder, ma continuiamo cliccando sulla UIWebView e aprendo il Connections Inspector. Noteremo che ci sono gi delle azioni denite (goBack, goForward, etc.). Dovremo solo collegare le azioni con i bottoni adeguati. Ecco le associazioni da fare: goBack con il bottone <, ovvero per tornare alla pagina precedente; goForward con il bottone >, ovvero per andare alla pagina successiva (della cronologia); reload con il bottone Ricarica, per ricaricare la pagina web. Se avete eseguito tutto correttamente avrete un risultato come questo:

Tutto molto semplice! Salviamo tutto e chiudiamo Interface Builder.

Guida pratica a#iPhone SDK

48

S CRIVIAMO
1 2 3 4 5 6 7

IL CODICE PER APRIRE LA PAGINA DE SIDERATA

Iniziamo aprendo il le MainView.h e completando la denizione della classe:


@interface MainView : UIView { IBOutlet UIWebView *webView; } @property (nonatomic, retain) IBOutlet UIWebView *webView; @end

Abbiamo fatto la solita denizione, che ormai abbiamo imparato a conoscere. Dobbiamo ora inserire il codice che ci carica la pagina desiderata e la mostra nella UIWebView. Utilizziamo un metodo che abbiamo gi visto in un tutorial precedente: awakeFromNib, che, come vi ricorderete, viene eseguito allavvio dellapplicazione. Aprite il le MainView.m e inserite il seguente codice:
1 2 3 4 5 6 7 8 9 10 11 @synthesize webView; - (void)awakeFromNib{ //indirizzo web da caricare NSString *indirizzo = @"http://www.bubidevs.net"; //crea un oggetto URL NSURL *url = [NSURL URLWithString:indirizzo]; NSURLRequest *requestObj = [NSURLRequest requestWithURL:url]; // visualizza la pagina nella UIWebView [webView loadRequest:requestObj]; }

Come potete vedere si tratta solo di quattro istruzioni! Deniamo, alla riga 5, lindirizzo che vogliamo aprire, mentre alle righe 6 e 7 inizializiamo i componenti necessari per poter visualizzare la pagina (non preoccupatevi troppo, sono sempre questi da utilizzare). Allistruzione 10, inne, settiamo i componenti che abbiamo appena creato nella UIWebView, in modo che venga mostrata la pagina web allutente. E se volessimo caricare dei le HTML che abbiamo in locale? Semplice, basta usare il susso le:// nel percorso. Ad esempio, utilizzando le://pagina1.html caricheremmo il le pagina1.hmtl che si dovrebbe trovare, per, nella stessa cartella in cui viene seguita lapplicazione. Semplice vero? Cliccate su Build and Go! e provate il vostro personalissimo browser!

Guida pratica a#iPhone SDK

49

Guida pratica a#iPhone SDK

50

Capitolo 9: UITableView, gestiamo le tabelle


Abbiamo no ad ora abbiamo analizzato dei componenti base, molto semplici sia da impostare che da utilizzare. Il componente pi utilizzato, per, sicuramente quello che gestisce le tabelle, ovvero la UITableView. In moltissime applicazioni, infatti, esse vengono utilizzate per mostrare delle informazioni allutente, che pu anche interagire con questi dati. In questo capitolo vedremo come denire una tabella, come inserire al suo interno dei valori e come denire dei comportamenti (ad esempio la cancellazione delle righe), necessari per renderla utilizzabile dallutente. Questo capitolo suddiviso in tre parti: 1.Creazione e denizione de#a tabe#a; 2.Inserimento di alcune funzionalit; 3.Implementazione de#a ricerca. Analizzeremo queste parti una alla volta, passo per passo, in modo da comprendere bene ogni singola cosa che andremo a realizzare.

P ARTE 1:

CREIAMO E DEFINIAMO LA TABELLA

La prima parte di questo tutorial dedicata alla creazione della struttura dellapplicazione: ne deniremo la graca, la lista degli elementi da visualizzare e come mostrarli allinterno delle celle. Il tutto sar fatto con la solita semplicit, sfruttando tutte le caratteristiche che XCode e lSDK ci mettono a disposizione, semplicando il nostro lavoro.

C REIAMO

UN NUOVO PROGET TO

In XCode, creiamo un nuovo progetto di tipo View-Based Application e chiamiamolo tableTutorial. Prima di denire la struttura graca, apriamo il le tableTutorialViewController.h e deniamo loggetto tabella che ci servir fra poco:
1 2 3 4 5 6 7 #import <UIKit/UIKit.h> @interface tableTutorialViewController : UIViewController { IBOutlet UITableView *tabella; } @end

Abbiamo gi visto questo modo di procedere nel primo tutorial, in cui abbiamo denito gli elementi via codice collegandoli poi tramite Interface Builder. Ora abbiamo fatto la stessa cosa.

Guida pratica a#iPhone SDK

51

Possiamo salvare il le, e fare doppio clic su tableTutorialViewController.xib, che ci aprir come al solito Interface Builder. Sar in questo le (che ha creato per noi XCode) che andremo a denire laspetto graco della nostra applicazione.

D EFINIAMO

LA STRUT TURA GRAFICA

Inseriamo nella vista un componente di tipo UITableView, in modo che occupi tutta la nostra vista. Ecco il risultato:

Iniziamo subito impostando le due propriet fondamentali di questa tabella. Clicchiamo sulla tabella e apriamo il Connections Inspector. Vedremo due oggetti gi deniti: dataSource, ovvero i dati che devono essere visualizzati nella tabella; delegate, ovvero il delegato di tale classe, concetto che abbiamo gi visto nei capitolo precedenti. Colleghiamo entrambi con il Files Owner (che troviamo nel pannello dei documenti), in modo da avere un risultato come questo:

Guida pratica a#iPhone SDK

52

Eseguire questo collegamento signica delegare alla classe tableTutorialViewController la gestione di questi due aspetti. In tale classe, quindi, dovremo denire tutti i metodi che il protocollo ci obbliga ad implementare. Ma di questo ci occuperemo tra poco. Colleghiamo, ora, il componente tabella che abbiamo denito allinizio di questo tutorial. Per fare ci, clicchiamo sul Files Owner dal pannello dei documenti e apriamo il Connections Inspector. Tra i vari oggetti presenti vedremo tabella, che dobbiamo collegare con la UITableView che abbiamo inserito inizialmente. Colleghiamola e, se avremo eseguito tutto correttamente, avremo un risultato come questo:

Possiamo salvare tutto e chiudere Interface Builder

I NSERIAMO

IL CODICE NECE SSARIO

Ora dobbiamo iniziare ad inserire il codice che denisce le propriet e il comportamento della nostra tabella. Iniziamo aprendo nuovamente il le tableTutorialViewController.h e completandolo nel seguente modo:
1 2 3 #import <UIKit/UIKit.h> @interface tableTutorialViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>{ IBOutlet UITableView *tabella; NSMutableArray *lista; }

4 5 6 7 8 9 @property (nonatomic, retain) IBOutlet UITableView *tabella; 10 @property (nonatomic, retain) NSMutableArray *lista; 11 12 @end

Come potete notare abbiamo inserito due istruzioni particolari, racchiuse tra <>. Questi sono i due protocolli che la nostra classe deve implementare per poter gestire la tabella. Alla riga 6, inoltre, abbiamo denito un array in cui inseriamo tutti gli elementi che devono poi essere visualizzati nella tabella. Notate che abbiamo utilizzato un NSMutableArray, questo

Guida pratica a#iPhone SDK

53

perch dovremo avere la possibilit di poter modicare gli elementi che lo compongono (analizzeremo meglio questo aspetto quando sar necessario). Alle righe 9 e 10 abbiamo denito le propriet degli oggetti, che utilizzeremo fra poco. Spostiamoci ora nel le tableTutorialViewController.m e iniziamo inseriamo questi metodi:
1 2 3 4 5 6 7 8 9 #import "tableTutorialViewController.h" @implementation tableTutorialViewController @synthesize tabella, lista;

- (void)viewDidLoad{ //elementi da visualizzare nella tabella lista = [[NSMutableArray alloc] initWithObjects:@"iPhone", @"iPod", @"iPod Touch", @"iMac", @"iBook", @"MacBook", @"MacBook Pro", @"Mac Pro", @"PowerBook", nil]; 10 } 11 12 //setta il numero di righe della tabella 13 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 14 return [lista count]; 15 }

Analizziamoli ora uno alla volta. Il primo metodo viewDidLoad (che funziona analogamente ad awakeFromNib), in cui deniamo larray che contiene gli elementi da visualizzare. Nellesempio abbiamo inserito alcuni prodotti della Apple, semplicemente utilizzando un metodo che ci permette di inserirli in fase di inizializzazione. Alla riga 13 abbiamo implementato un metodo che denisce il numero di righe della nostra tabella. Avremmo potuto anche inserire come istruzione return 9, in quanto gli elementi del nostro array sono 9. Con listruzione che abbiamo utilizzato, per, rendiamo il nostro codice pi essibile, e nel caso volessimo variare il numero di elementi nel nostro array non dovremmo modicare anche questo metodo. Questa, quindi, la soluzione migliore da adottare sempre. Ci manca un ultimo metodo, quello che si occupa di inserire questi elementi allinterno delle singole celle. Inseriamo, quindi, questo metodo:

Guida pratica a#iPhone SDK

54

1 2 3 4 5 6 7 8 9 10 11 12 13 14

//settiamo il contenuto delle varie celle - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellID"]; if (cell == nil){ cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"cellID"] autorelease]; //setta lo stile con cui vengono selezionate le righe cell.selectionStyle = UITableViewCellSelectionStyleNone; } //inseriamo nella cello l'elemento della lista corrispondente cell.text = [lista objectAtIndex:indexPath.row]; return cell; }

Questo il metodo (fondamentale ed obbligatorio) che si occupa di settare in maniera corretta le celle della tabella. Alla riga 4 troviamo la dichiarazione di una cella, che viene poi allocata alla riga 7. Con listruzione presente alla riga 9 deniamo come deve essere laspetto delle righe quando vengono selezionate dallutente. Con questa istruzione lutente non potr selezionare nessuna riga, se invece la togliamo avremo la classica selezione con sfondo blu. Alla riga 12, inne, settiamo il valore contenuto nella cella: esso deve essere letto dallarray, nella posizione uguale a quella della riga (ricordatevi che sia la numerazione dellarray che delle celle parte da zero). Cliccate ora su Build and Go!: la nostra tabella inizia a prendere forma!

Guida pratica a#iPhone SDK

55

P ARTE 2: I NSERIAMO ALCUNE

FUNZIONALIT

Abbiamo visto come denire una tabella. In questa seconda parte vedremo come aggiungere due funzionalit davvero molto importanti: la cancellazione delle singole celle e la possibilit di renderle selezionabili. Vedrete che per entrambe le caratteristiche dovremo inserire davvero poco codice, in quanto gi tutto denito.

A GGIUNGIAMO

LA BARRA DI NAVIGAZIONE

Iniziamo aprendo nuovamente il le tableTutorialViewController.xib e inserendo nella vista una barra UINavigationBar. Ecco il risultato che dovete ottenere:

Dobbiamo ora denire un oggetto che si riferisca a questa barra. Dal pannello dei documenti selezioniamo Files Owner e apriamo il Connections Inpsector. In precedenza abbiamo gi collegato lelemento tabella, ora dovremo collegare navigationItem con la UINavigationBar che abbiamo appena inserito. Ecco come appare il pannello dopo il collegamento:

Guida pratica a#iPhone SDK

56

Questo navigationItem un oggetto gi incluso in ogni vista, che quindi possiamo sfruttare senza problemi. Avremmo potuto denire un nuovo oggetto (come abbiamo fatto per la tabella), ma sfruttare questo pi elegante e ci permette un risparmio di memoria. Salviamo e chiudiamo Interface Builder.

P ERMET TIAMO

LA CANCELLAZIONE DI UNA RIGA

Per prima cosa, dobbiamo inserire il bottone che permetta allutente di attivare la possibilit di modicare la tabella. Per fare ci, sfrutteremo un altro componente gi presente nelle classi UIViewController. Apriamo, quindi, il le tableTutorialViewController.m e inseriamo il seguente codice:
1 2 3 4 5 6 7 8 9 10 11 #import "tableTutorialViewController.h" @implementation tableTutorialViewController @synthesize tabella, lista;

- (void)viewDidLoad{ // aggiungiamo il bottone per modificare la tabella self.navigationItem.rightBarButtonItem = self.editButtonItem; //elementi da visualizzare nella tabella lista = [[NSMutableArray alloc] initWithObjects:@"iPhone", @"iPod", @"iPod Touch", @"iMac", @"iBook", @"MacBook", @"MacBook Pro", @"Mac Pro", @"PowerBook", nil]; 12 } 13 14 - (void)setEditing:(BOOL)editing animated:(BOOL)animated { 15 [super setEditing:editing animated:animated]; 16 [tabella setEditing:editing animated:animated]; 17 } 18

La prima cosa che abbiamo fatto stata quella di aggiungere listruzione alla riga 9 nel metodo viewDidLoad. Abbiamo inserito il bottone editButtonItem, che proprio il componente che lSDK ci mette a disposizione. La particolarit di questo elemento consiste nel fatto che quando attiva la modica della tabella, il bottone ha sfondo blu e riporta la scritta Done, mentre se la tabella non modicabile lo sfondo del solito colore e la scritta Edit. Volendo, potete inserire questo bottone a sinistra, semplicemente usando leftBarButtonItem al posto di rightBarButtonItem. Alla riga 14 abbiamo invece implementato il metodo che si occupa della modica della tabella. Le istruzioni da utilizzare sono sempre queste due: la prima richiama lo stesso metodo ma della superclasse (questo un aspetto classico della programmazione ad oggetti), mentre la seconda richiama il metodo stesso sulla nostra tabella ( una funziona ricorsiva quindi). Ovviamente,

Guida pratica a#iPhone SDK

57

sar il metodo della superclasse che si occuper di abilitare o disabilitare la possibilit di eliminare le righe, rendendo il nostro lavoro molto pi veloce. I due metodi che abbiamo appena denito permettono allutente di cancellare una riga qualsiasi. Tuttavia, se provate ad eseguire lapplicazione, noterete che cancellando una riga essa non viene rimossa dalla tabella. Questo avviene perch non abbiamo ancora concluso di implementare questa funzionalit. Inseriamo quindi questo metodo:
// Elimina l'elemento dalla tabella e dalla lista - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 3 4 //controlla se l'azione compiuta un'eliminazione 5 if (editingStyle == UITableViewCellEditingStyleDelete) { 6 //elimina l'elemento dalla lista 7 [lista removeObjectAtIndex:indexPath.row]; 8 //elimina le'elemento dalla tabella 9 [tabella deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 10 11 } 12 } 1 2

Come possiamo notare dalla struttura un po complicata, questo un metodo del protocollo UITableView, proprio come quello che abbiamo implementato nella prima parte. Il costrutto if (riga 5) esegue un controllo che, come spiega il commento, controlla se lazione eseguita sulla tabella di cancellazione di una riga. Direte voi: Cosa posso fare daltro? Per ora niente, perch la nostra tabella supporta solo leliminazione di una riga, ma volendo si potrebbe implementare anche linserimento di una nuova riga, oppure altre azioni. sempre questo metodo che si occupa di gestire tutte le azioni sulla tabella. Ecco spiegata la necessit di questo controllo. Tornando al codice, allinterno dellif possiamo notare due istruzioni, che eliminano lelemento sia dalla lista (riga 7) che dalla tabella (riga 9). In questo modo la cancellazione di una riga davvero implementata.

R ENDIAMO

LE CELLE SELEZIONABILI

Vediamo ora di implementare unaltra funzione. Vogliamo che quando lutente seleziona una cella appaia un pop-up che contenga il nome dellelemento selezionato. Ovviamente questa azione non ha una grande utilit, ma vi permetter di imparare come gestire le selezioni dellutente e vedrete, inoltre, come creare un pop-up. Prima di implementare il metodo necessario, eliminate dal metodo
tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath;

Guida pratica a#iPhone SDK

58

la seguente istruzione (vi ho spiegato nella prima parte a cosa serviva):


1 cell.selectionStyle = UITableViewCellSelectionStyleNone;

altrimenti le celle non saranno selezionabili. Nel solito le tableTutorialViewController.m inserite ora questo metodo:
1 // Se selezioniamo una riga appare un pop-up con l'elemento in questione 2 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 3 UIAlertView *popUp = [[UIAlertView alloc] initWithTitle:@"Hai selezionato:" message:[lista objectAtIndex:indexPath.row] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; 4 [popUp show]; 5 [popUp release]; 6 }

Questo il metodo che si occupa di eseguire una certa azione quando lutente seleziona una cella. Alla riga 3 possiamo notare la denizione del pop-up, che conterr un messaggio con il nome della cella selezionata. possibile creare pop-up con diversi bottoni o pi messaggi, vi baster guardare la documentazione per trovare tutte le varianti possibili. Alla riga 6, inne, viene mostrato il pop-up appena denito. Cliccate ora su Build and Go! e testate la nuova tabella!

Guida pratica a#iPhone SDK

59

P ARTE 3: I MPLEMENTIAMO

LA RICERCA

Nella terza e ultima parte di questo lungo tutorial dedicato alle tabelle, vedremo come aggiungere un box di ricerca. Il comportamento sar del tutto simile a quello della ricerca presente nellapplicazione nativa Contatti. Non sar un compito semplicissimo, per vi potr tornare utile in moltissime applicazioni, quindi cercate di capire il pi possibile!

A GGIUNGIAMO

IL BOX DI RICERCA

Prima di lavorare con Interface Builder, apriamo il le tableTutorialViewController.h e dichiariamo il seguente elemento:
1 IBOutlet UISearchBar *barraRicerca;

Salviamo il le e facciamo doppio clic su tableTutorialViewController.xib per aprire IB, in cui inseriremo lelemento graco necessario: una UISearchBar, ottenendo un risultato come questo:

Ovviamente questa la soluzione pi semplice, volendo potreste inserire un bottone che, quando premuto, fa apparire la barra, oppure integrare il box di ricerca direttamente nella UINavigationBar principale. Ora dobbiamo denire questo elemento e le sue propriet. Dal pannello dei documenti selezioniamo il Files Owner e apriamo Connections Inspector. Nella sezione Outlets colle-

Guida pratica a#iPhone SDK

60

ghiamo lelemento barraRicerca con la UISearchBar che abbiamo appena inserito; in Referencing Outlets colleghiamo delegate con la barra. Se avrete eseguito tutto correttamente avrete un risultato come questo:

Salviamo tutto e chiudiamo Interface Builder.

M ODIFICHIAMO

I METODI GI E SISTENTI

Prima di implementare la ricerca vera e propria, dobbiamo fare delle piccole modiche ai metodi gi presenti nel nostro progetto. Iniziamo aprendo il le tableTutorialViewController.h e completiamo cos la denizione della classe:
1 2 3 #import <UIKit/UIKit.h>

@interface tableTutorialViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>{ 4 IBOutlet UITableView *tabella; 5 6 IBOutlet UISearchBar *barraRicerca; 7 8 NSMutableArray *lista; 9 10 NSMutableArray *filteredListContent; 11 } 12 13 @property (nonatomic, retain) IBOutlet UITableView *tabella; 14 @property (nonatomic, retain) NSMutableArray *lista; 15 16 @property (nonatomic, retain) UISearchBar * barraRicerca; 17 @property (nonatomic, retain) NSMutableArray *filteredListContent; 18 19 @end

Guida pratica a#iPhone SDK

61

Alla riga 6 c la denizione della barra di ricerca che abbiamo inserito allinizio di questo terzo tutorial. Alla riga 10, invece, abbiamo dichiarato una nuova lista, che conterr gli elementi ltrati, ovvero quelli che corrispondono al criterio di ricerca. Ora dobbiamo modicare i metodi che si occupano dellinizializzazione della tabella. Iniziamo dal metodo viewDidLoad e dalla funzione @synthetize:
1 2 3 4 5 6 7 @synthesize tabella, lista, barraRicerca, filteredListContent; - (void)viewDidLoad { // aggiugiamo il bottone per modificare la tabella self.navigationItem.rightBarButtonItem = self.editButtonItem; // elementi da visualizzare nella tabella lista = [[NSMutableArray alloc] initWithObjects: @"iPhone", @"iPod", @"iPod Touch", @"iMac", @"iBook", @"MacBook", @"MacBook Pro", @"Mac Pro", @"PowerBook", nil]; // crea la lista filtrata, inizializzandola con il numero di elementi dell'array "lista" filteredListContent = [[NSMutableArray alloc] initWithCapacity: [lista count]]; //inserisce in questa nuova lista gli elementi della lista originale [filteredListContent addObjectsFromArray: lista]; // disabilita l'autocorrezione (nel box di ricerca) barraRicerca.autocorrectionType = UITextAutocorrectionTypeNo; // disabilita la prima lettera maiuscola (nel box di ricerca) barraRicerca.autocapitalizationType = UITextAutocapitalizationTypeNone; // nasconde il bottone per uscire dalla ricerca barraRicerca.showsCancelButton = NO; }

8 9 10 11 12 13 14 15 16 17 18 19 20

Alla riga 10 e 11 abbiamo inizializzato il nuovo array, che ci servir nellalgoritmo di ricerca. Inizialmente questa lista coincider con quella degli elementi iniziali, mentre poi verr modicata mentre lutente inserisce la stringa di ricerca. Nelle righe 15, 17 e 19 abbiamo denito dei comportamenti per il nostro box di ricerca, come potete capire dai commenti. Il secondo metodo da modicare numberOfRowsInSection. Ecco il nuovo codice:
1 //setta il numero di righe della tabella 2 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 3 //il numero di righe deve corrispondere al numero di elementi della lista 4 return [filteredListContent count]; 5 }

Questa modica va eseguita in quanto la tabella ora non pi composta dagli elementi della

Guida pratica a#iPhone SDK

62

lista originale, ma da quelli della lista ltrata, ovvero di quegli elementi selezionati mediante la ricerca. Ovviamente se lutente non esegue nessuna ricerca, gli elementi della lista ltrata corrisponderanno agli elementi della lista originale. Se vi chiaro questo ragionamento, facile intuire quali saranno i prossimi due metodi da modicare: il primo cellForRowAtIndexPath:, ovvero il metodo che si occupa di inserire i valori nelle celle. Modicate lultima istruzione al suo interno nella seguente maniera:
1 2 //inseriamo nella cella l'elemento della lista corrispondente cell.text = [filteredListContent objectAtIndex:indexPath.row];

L altro metodo da modicare, invece, sar didSelectRowAtIndexPath: e anche in questo caso lunica modica riguarda proprio la lista di riferimento.
1 // Se selezioniamo una riga appare un pop-up con l'elemento in questione 2 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 3 UIAlertView *popUp = [[UIAlertView alloc] initWithTitle:@"Hai selezionato:" message:[filteredListContent objectAtIndex:indexPath.row] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; 4 [popUp show]; 5 [popUp release]; 6 }

Abbiamo cos eseguito tutte le modiche necessarie!

I MPLEMENTIAMO

LA RICERCA

arrivato il momento di implementare la ricerca vera e propria. Prima di mostrarvi i passaggi necessari, devo premettere che il codice non stato scritto da me, ma lho preso da un esempio realizzato dalla stessa Apple. I commenti, quindi, saranno davvero pochi, anche perch non fondamentale capire come funziona tale algoritmo, in quanto lo stesso codice si pu utilizzare in qualsiasi altra applicazione che necessiti di una ricerca. Iniziamo con due metodi accessori, ovvero non legati direttamente allalgoritmo di ricerca. Ecco i due metodi da inserire nel le tableTutorialViewController.m:
1 2 3 4 5 6 7 8 9 10 11 12 // metodo chiamato quando l'utente inizia ad inserire la chiave di ricerca - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{ // visualizza il bottone per uscire dalla ricerca barraRicerca.showsCancelButton = YES; // disattiviamo la possibilit di modificare le celle della tabella self.navigationItem.rightBarButtonItem.enabled = FALSE; } // metodo richiamato quando l'utente ha terminato la ricerca - (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar{ // nascondiamo il bottone "Cancel" del box di ricerca barraRicerca.showsCancelButton = NO; }

Guida pratica a#iPhone SDK

63

Il primo metodo viene richiamato quando lutente inizia ad inserire la chiave di ricerca: mostriamo il bottone per annullare la ricerca e disattiviamo il bottone per modicare le celle (questo per non creare strani comportamenti). Il secondo metodo, invece, viene richiamato quando la ricerca terminata. Eccovi altri due metodi da aggiungere:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 // metodo richiamato quando il bottone "Cancel" viene premuto - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{ /* se l'utente esegue una ricerca valida, ma poi la annulla dobbiamo inserire i valori originali nella tabella*/ if (barraRicerca.text.length > 0){ [filteredListContent removeAllObjects]; [filteredListContent addObjectsFromArray: lista]; } // ricarichiamo la tabella [tabella reloadData]; [barraRicerca resignFirstResponder]; //azzeriamo il box di ricerca barraRicerca.text = @""; //riabilitiamo il tasto per la modifica della tabella self.navigationItem.rightBarButtonItem.enabled = TRUE; } // metodo richiamato quando il bottone "Done" viene premuto - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{ // se il box di ricerca vuoto abilitiamo la modifica della tabella if ([filteredListContent count] == [lista count]) self.navigationItem.rightBarButtonItem.enabled = TRUE; else self.navigationItem.rightBarButtonItem.enabled = FALSE; [barraRicerca resignFirstResponder]; }

Il primo metodo viene richiamato alla pressione del tasto Cancel che appare quando lutente inizia ad inserire la sua chiave di ricerca. Questo metodo dovr ripristinare la tabella al suo stato originale, ovvero con gli elementi della lista di partenza, e settando in maniera corretta tutte le caratteristiche desiderate. Discorso simile vale per il secondo metodo, che viene richiamato quando si preme Done sulla tastiera virtuale. I commenti presenti nei due metodi dovrebbero rendere tutte le istruzioni comprensibili. Quello che manca ora lalgoritmo di ricerca vero e proprio, che il seguente:

Guida pratica a#iPhone SDK

64

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

// algoritmo di ricerca - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{ // azzeriamo la lista con gli elementi filtrati [filteredListContent removeAllObjects]; // search the table content for cell titles that match "searchText" // if found add to the mutable array and force the table to reload NSString *cellTitle; for (cellTitle in lista){ NSComparisonResult result = [cellTitle compare:searchText options:NSCaseInsensitiveSearch range:NSMakeRange(0, [searchText length])]; if (result == NSOrderedSame){ [filteredListContent addObject:cellTitle]; } } [tabella reloadData]; }

Per questo algoritmo non voglio spendere parole, in quanto, come detto in precedenza, stato scritto da Apple, quindi non posso permettermi di fare modiche! Cliccate ora su Build and Go!, se avete eseguito tutto correttamente si aprir la vostra applicazione!

Guida pratica a#iPhone SDK

65

Capitolo 10: XML


Dopo aver visto molti componenti, in questo capitolo vedremo come integrare una tecnologia molto utilizzata, specialmente in ambito web: stiamo parlando di XML. Vedremo, quindi, come leggere un le XML, da cui ricaveremo delle informazioni che abbiamo salvato. Questa operazione verr eseguita in locale (ovvero il le xml sar allinterno del nostro progetto), ma nulla vieta di avere il le caricato su un server web da cui accediamo tramite la nostra applicazione.

C OSA XML?
XML un metalinguaggio (in quanto non un linguaggio di programmazione vero e proprio) di markup, ovvero un linguaggio che consente di estendere o controllare il comportamento di altri linguaggi. Il linguaggio di markup pi famoso sicuramente lHTML, che ha molte analogie con lXML. XML lacronimo di eXtensible Markup Language, da cui possiamo capire la caratteristica fondamentale di questo linguaggio: ci permette di creare tag personalizzati, in base alle proprie esigenze. Sar pi semplice comprendere come funziona questo linguaggio mediante un esempio:

La prima riga denisce la versione di XML in uso e la codica utilizzata (secondo le norme ISO). Dalla seconda riga in poi, invece, troviamo dei tag personalizzati, che vanno a modellare dei dati a nostro piacimento. Possiamo vedere come abbiamo denito un tag generale studenti, che viene iniziato alla seconda riga e concluso allultima. Nel mezzo troviamo, invece, altri tag, che riportano le informazioni che vogliamo memorizzare, per poi utilizzarle a nostro piacimento. Ci sono alcune piccole regole da rispettare nella struttura XML:

Guida pratica a#iPhone SDK

66

1. I tag non possono iniziare con numeri o caratteri speciali e non possono contenere spazi. Corretti: <nome>, <cognome>, <dataDiNascita> Errati: <&soldi>, <12peso>, <anno di nascita> 2. I tag devono essere bilanciati (ogni tag aperto deve essere chiuso) Corretto: <nome>Andrea</nome> Errato: <nome>Andrea 3. I tag non devono contenere errori di annidamento. Ecco alcuni esempi errati:

4. Si possono inserire degli attributi allinterno dei tag; la struttura sar quindi la seguente: <nometag attributo1=valore1 attributo2=valore2> V alore </nometag> I nostri elementi, quindi, potranno essere scritti anche nella seguente maniera:

Questa struttura del tutto uguale a quella precedente. Notate che in questo caso non abbiamo usato il tag di chiusura, ma abbiamo inserito / allinterno del tag stesso proprio per indicare che quel tag non ha elemento di chiusura. Quello che cambier sar solamente il modo di leggere i valori via codice.

Guida pratica a#iPhone SDK

67

XML

NEL

SDK

DI I P HONE

Per ora abbiamo fatto una panoramica su XML in generale, presentando gli aspetti fondamentali di tale linguaggio. Ma come possiamo integrarlo con le nostre applicazioni?L oggetto che si occupa di recuperare i dati da un le XML viene detto parser. Esistono vari tipi di parser (diversi per linguaggi e tecnologie), noi andremo ad utilizzare SAX. La caratteristica di questo parser sta nel fatto che processa i documenti linea per linea: dati a cui si acceduto in precedenza non possono essere riletti senza la rielaborazione dellintero documento. Pu essere uno svantaggio, ma lunico parser disponibile nel SDK per iPhone!!

C REIAMO

LA STRUT TURA GRAFICA

Iniziamo ora a creare la nostra applicazione. Creiamo un nuovo progetto di tipo Window-Based Application e chiamiamolo xmlTutorial. Prima di denire laspetto graco, per, dichiariamo i componenti che ci servono. Apriamo il le xmlTutorialViewController.h e modicatelo cos:
1 2 3 4 5 6 7 8 9 10 11 #import <UIKit/UIKit.h> @interface xmlTutorialViewController : UIViewController { IBOutlet UITextView *textArea; NSString *path; } -(IBAction)avviaParsing; @end

Abbiamo dichiarato una TextView in cui inseriremo i dati letti dal le xml, unazione, che andr collegata ad un bottone (tale azione far iniziare il processo di parsing) e una stringa che conterr il percorso del le xml. Possiamo salvare il le e dedicarci alla struttura graca dellapplicazione. Apriamo ora il le xmlTutorialViewControlle.xib, che avvier Interface Builder. Nella nostra applicazione, inseriamo un bottone e una TextView, di dimensioni abbastanza ampie, in quanto dovr contenere tutti i valori letti dal le xml. Dovreste ottenere un risultato come questo:

Guida pratica a#iPhone SDK

68

Ora, selezionando la UITextView, entriamo in Attributes Inspector e togliamo la spunta a Editable:

questo perch non vogliamo che lutente possa modicare i valori presenti nella TextView (ovvero deve essere di sola lettura). Dal pannello dei documenti (Tools -> Reveal in Document Window) selezioniamo Files Owner, ovvero la classe che gestisce il nostro le.

Guida pratica a#iPhone SDK

69

Apriamo il Connections Inspector e potremo vedere alcuni elementi, pi i due che abbiamo denito noi allinizio del nostro progetto. Colleghiamo textArea con la UITextView presente nella nostra vista, e lazione avviaParsing con il bottone: quando apparir il men con tutte le azioni disponibili, scegliamo Touch Up Inside. Se avrete eseguito tutto correttamente avrete un pannello che si presenter cos:

Abbiamo terminato la creazione della struttura graca. Possiamo salvare tutto e chiudere Interface Builder.

S CRIVIAMO

IL CODICE NECE SSARIO

Prima di procedere con il codice necessario, dobbiamo inserire allinterno del progetto il le xml con i nostri dati. Se avete capito la struttura di tali le, potete creare uno a vostro piacimento (fate attenzione a salvarlo con estensione .xml), altrimenti copiate quello presentato nel primo capitolo. Apriamo ora il le xmlTutorialViewController.m e deniamo il seguente metodo:

Guida pratica a#iPhone SDK

70

1 2 3 4 5 6

// Metodo eseguito all'avvio della vista - (void)viewDidLoad { [super viewDidLoad]; // definiamo il percorso del file xml NSString *pathProgetto = [[NSBundle mainBundle] bundlePath]; path = [[NSString alloc] initWithString:[pathProgetto stringByAppendingPathComponent:@"dati.xml"]]; 7 }

Questo metodo viene eseguito allavvio della vista, e ci permette di denire dei comportamenti che devono essere eseguiti prima di ogni altra cosa. Con le due istruzioni che abbiamo inserito deniamo il percorso del nostro le dati.xml: esso viene cercato allinterno della cartella del nostro progetto. Queste istruzioni sono molto importanti, in quanto non viene denito un percorso assoluto (soluzione sempre sconsigliabile e spesso errata), ma viene denito il percorso eettivo in cui si trova il le. Dobbiamo ora denire lazione che viene eseguita quando premiamo sul pulsante. Ecco il codice da inserire:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 -(IBAction)avviaParsing{ //Bisogna convertire il file in una NSURL altrimenti non funziona NSURL *xmlURL = [NSURL fileURLWithPath:path]; // Creiamo il parser NSXMLParser *parser = [[ NSXMLParser alloc] initWithContentsOfURL:xmlURL]; // Il delegato del parser e' la classe stessa (self) [parser setDelegate:self]; //Effettuiamo il parser BOOL success = [parser parse]; //controlliamo come andata l'operazione if(success == YES){ //parsing corretto } else { //c' stato qualche errore... } // Rilasciamo l'oggetto NSXMLParser [parser release]; }

Le istruzioni alle righe 3 e 5 ci permettono di denire il parser, partendo dal percorso del nostro le. Alla riga 9 avviamo il processo di parsing, salvando il risultato in una variabile booleana: se essa vale YES la conversione si conclusa senza errori (riga 12), altrimenti c stato un errore (che potrebbe essere dovuto ad errori nella struttura del le xml oppure ad errori di scrittura del codice). Come potete vedere non si tratta di codice complesso, sono poche istruzioni che dovrebbero risultarvi chiare.

Guida pratica a#iPhone SDK

71

La parte che viene ora quella che si occupa di leggere i dati dal le xml. Iniziamo inserendo questo metodo:
1 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict { if ([elementName isEqualToString:@"studenti"]){ [textArea setText:[[NSString alloc] initWithFormat:@"%@\nInizio studenti",textArea.text]]; } else if([elementName isEqualToString:@"studente"]){ [textArea setText:[[NSString alloc] initWithFormat:@"%@\nNuovo studente",textArea.text]]; } else if([elementName isEqualToString:@"matricola"]) { [textArea setText:[[NSString alloc] initWithFormat:@"%@\nMatricola: ",textArea.text]]; } else if([elementName isEqualToString:@"cognome"]) { [textArea setText:[[NSString alloc] initWithFormat:@"%@\nCognome: ",textArea.text]]; } else if([elementName isEqualToString:@"nome"]) { [textArea setText:[[NSString alloc] initWithFormat:@"%@\nNome: ",textArea.text]]; } }

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Come potete osservare, vi sono una serie di controlli if, che vanno a testare lelemento corrente, per riconoscerlo e per scrivere una stringa adeguata nella textArea che abbiamo predisposto. Questo processo possibile perch conosciamo a priori la struttura del le xml: questo quasi sempre vero, in quanto sarebbe quasi impossibile leggere un le xml di cui non conosciamo la struttura interna. Il metodo viene, ovviamente, richiamato ogni volta che il parser incontra un nuovo elemento, cio lapertura di un tag. Per completare il nostro programma mancano solo due metodi:

Guida pratica a#iPhone SDK

72

1 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 2 [textArea setText:[[NSString alloc] initWithFormat:@"%@%@",textArea.text,string]]; 3 } 4 5 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { 6 [textArea setText:[[NSString alloc] initWithFormat:@"%@\nFine elemento: %@",textArea.text,elementName]]; 7 }

Il primo viene richiamato quando il parser incontra un valore racchiuso tra due tag (linformazione vera e propria). Nel nostro caso ci limitiamo a inserirla nella textArea, per potreste fare delle operazioni pi o meno complesse sulle informazioni che leggete dal le. L ultimo metodo, invece, viene richiamato quando il parser incontra un tag di chiusura. Anche in questo caso lunica azione che faremo sar quello di inserire una stringa nella textArea. Possiamo nalmente cliccare su Build and Go! e testare la nostra applicazione funzionante!

Guida pratica a#iPhone SDK

73

Capitolo 11: Gestire pi viste create con IB


In questo capitolo aronteremo un argomento abbastanza ostico di XCode, ovvero la gestione di pi viste create con Interface Builder. Questo uno strumento davvero ottimo che ci permette di creare la parte graca della nostra applicazione senza grossi sforzi, ma a volte diventa problematico gestire tutte le viste create gracamente via codice. In questo tutorial vedremo come creare due viste distinte, e come passare da una allaltra mediante un semplice bottone. Unoperazione semplice, che per vi far capire il meccanismo che sta alla base.

C REIAMO

LA VISTA PRINCIPALE

Iniziamo come sempre creando un nuovo progetto di tipo View-Based Application e chiamiamolo viewTutorial. Prima di fare qualsiasi altra operazione, selezioniamo eliminiamo il le viewTutorialViewController.xib presente nella sezione Resources. Baster cliccare con il tasto destro sul le, selezionare Delete e poi cliccare su Also move to Trash. Una volta eseguite queste semplici operazioni, andiamo a creare linterfaccia graca. Facciamo doppio click sul le MainWindow.xib, si aprir cos lInterface Builder, con cui ormai abbiamo gi preso conoscenza. Selezioniamo la vista della nostra applicazione, e apriamo lAttribute Inspector. Nel campo NIB Name eliminiamo la voce viewTutorialViewController (semplicemente cancellando il testo), ovvero il le che abbiamo cancellato in precedenza.

Se premiamo poi invio e torniamo a selezionare la vista vedremo che essa ha mutato la scritta centrale, ed ora apparir cos:

Guida pratica a#iPhone SDK

74

Ora, dalla libreria selezioniamo un componente di tipo View e trasciniamolo nella nostra applicazione. Andiamo poi in Identity Inspector e in Class scriviamo MainView:

Abbiamo creato la vista principale della nostra applicazione. In questo tutorial questa vista non ci servir a molto, ma avr solo il compito di ospitare le altre viste, che verranno richiamate da apposite azioni. Ora, salviamo subito la classe MainView relativa a questa vista, selezionando File -> Write Class Files e inserendola nella cartella Classes del nostro progetto, ricordandoci poi di mettere la spunta nella nestra successiva che apparir.

C REIAMO

LA VISTA ( E LA CLASSE )

V ISTA U NO

Iniziamo ora a creando una prima vista, che chiameremo vistaUno, e verr caricata di default allavvio dellapplicazione. Tramite un bottone contenuto in questa vista sar poi possibile aprire una seconda vista, che chiameremo vistaDue. Iniziamo, per, a creare la prima.

Guida pratica a#iPhone SDK

75

Inseriamo allinterno del le MainWindow.xib una vista (una UIView), in modo da avere un pannello dei documenti come questo:

Facciamo ora doppio clic sulla vista appena inserita, si aprir (ovviamente) completamente vuota. Inseriamo i componenti a nostro piacimento, limportante che ci sia almeno un bottone, avendo un risultato simile a questo:

Ora dobbiamo, come al solito, denire gli elementi e le azioni. Entriamo nel pannello Identity Inspector, e inseriamo i seguenti componenti (dichiarando anche la classe VistaDue):

Guida pratica a#iPhone SDK

76

Come potete vedere abbiamo dichiarato la classe come VistaUno, e abbiamo inserito un componente mainView, che si riferisce alla vista principale, la MainView. Abbiamo, inoltre, dichiarato unazione vaiAsecondaView, che dovremo associare al bottone presente in questa vista. Per fare ci, andiamo in Connections Inspector, e colleghiamo lazione vaiAsecondaView al bottone, selezionando Touch Up Inside quando appare il solito pop-up. Colleghiamo, inne, lelemento mainView con la vista principale, quella che abbiamo creato inizialmente, trascinando il solito pallino proprio sulla vista MainView. Se abbiamo eseguito tutto correttamente dovremmo avere un risultato come questo:

Abbiamo cos congurato correttamente la prima vista da Interface Builder. Salviamo anche questa classe dal solito men File -> Write Class Files e assicurandoci che appaia il nome VistaUno per la classe (se non appare signica che avete sbagliato qualcosa). Salviamo tutto e chiudiamo pure Interface Builder.

Guida pratica a#iPhone SDK

77

F ACCIAMO
ZIONE

CARICARE LA PRIMA VISTA ALL AVVIO DELL APPLICA-

Ora dobbiamo fare in modo che questa vista (la VistaUno) venga caricata in automatico allavvio dellapplicazione. Iniziamo a completare la dichiarazione di tale classe entrando nel le VistaUno.h. Completiamo il codice presente nel seguente modo:
1 2 3 4 5 6 7 8 9 10 11 12 #import <UIKit/UIKit.h> #import <Foundation/Foundation.h> @class MainView; @interface VistaUno : UIView { IBOutlet MainView *mainView; } - (IBAction)vaiAsecondaView; @end

Abbiamo solamente denito la superclasse alla riga 4, niente di strano. Implementiamo ora il metodo vaiAsecondaView. Il codice da inserire nel le VistaUno.m il seguente:
1 2 3 4 5 6 7 8 9 10 #import "VistaUno.h" #import "MainView.h" @implementation VistaUno - (IBAction)vaiAsecondaView { [mainView vaiAsecondaView]; } @end

Come potete notare questo metodo non compie nessuna azione sulle viste, ma richiama un metodo di mainView (che andremo a denire in seguito) che si occuper della gestione di questa azione. Torniamo ora nella classe MainView, a cui dobbiamo dire di caricare allavvio la vistaUno. Apriamo il le MainView.h e, anche in questo caso, completiamo il codice gi presente nel seguente modo:

Guida pratica a#iPhone SDK

78

1 2 3 4 5 6 7 8 9 10

#import <UIKit/UIKit.h> #import <Foundation/Foundation.h> @class VistaUno; @interface MainView : UIView { IBOutlet VistaUno *vistaUno; } @end

Alla riga 7 viene denita un oggetto vistaUno, che andr poi collegata proprio con tale vista. Ma come facciamo a caricarla allavvio? Come ormai dovreste ben sapere, esiste un metodo che viene eseguito proprio allavvio dellapplicazione: si tratta di awakeFromNib. Entriamo, quindi, in MainView.m e inseriamo il seguente codice:
1 2 3 4 5 6 7 8 9 #import "MainView.h" @implementation MainView -(void)awakeFromNib{ [self addSubview:vistaUno]; } @end

Questo metodo non fa altro che settare la vistaUno come Subview. Abbiamo nito? Quasi! Ci manca ancora una piccola cosa. Dobbiamo collegare la vistaUno che abbiamo appena dichiarato in MainView, con la vista eettiva che vogliamo che venga caricata. Questa operazione va eseguita, come sempre, in Interface Builder. Salviamo quindi tutti i le (io preferisco eseguire un Build per essere pi sicuro) ed entriamo in Interface Builder, aprendo il le MainWindow.xib. Entrando, ora, in Connections Inspector della vista MainView vedremo che comparso un nuovo elemento, ovvero proprio la vistaUno che abbiamo appena dichiarato. La nostra nestra delle connessioni avr il seguente aspetto:

Guida pratica a#iPhone SDK

79

Dobbiamo semplicemente collegare questo elemento con la vista che vogliamo far caricare allavvio, ovvero la VistaUno che abbiamo creato poco fa (per intenderci, quella composta dalluno in grande e dal bottone). Trasciniamo il pallino che troviamo a anco di vistaUno sulla vista corretta. Se abbiamo fatto le cose in maniera corretta avremo questo risultato:

Chiudiamo Interface Builder salvando tutto. Clicchiamo ora su Build and Go! e se abbiamo eseguito tutto in maniera corretta si aprir la nostra applicazione:

Guida pratica a#iPhone SDK

80

C REIAMO

LA VISTA ( E LA CLASSE )

V ISTA D UE

Abbiamo, no ad adesso, creato e impostato la prima vista. Dobbiamo creare ora anche una seconda vista, che verr aperta cliccando sul bottone presente nella nostra applicazione. Il procedimento lo stesso che abbiamo appena visto, quindi in questa seconda parte andremo pi veloci. Inseriamo una nuova vista nel nostro le MainWindow.xib (come fatto per la VistaUno) e inseriamo gli elementi a nostro piacere, avendo cura di inserire almeno un bottone, che ci servir per tornare alla vistaUno. La nostra vista si presenter come questa:

I componenti e le azioni da impostare saranno le stesse della VistaUno, quindi il vostro pannello Identity Inspector apparir cos:

Guida pratica a#iPhone SDK

81

Mentre il pannello Connections Inspector avr i seguenti elementi (che dobbiamo collegare proprio come fatto per VistaUno):

Salviamo la nuova classe VistaDue e aggiungiamola come sempre al nostro progetto. Salviamo tutto e chiudiamo pure Interface Builder.

I MP OSTIAMO

LE AZIONI PER MUOVERCI TRA LE VISTE

Prima di procedere allinserimento del codice che controlla la navigazione tra le viste, dobbiamo concludere la dichiarazione della classe VistaDue (come abbiamo gi fatto nel punto 4 per VistaUno). Aggiungiamo il seguente codice al le VistaDue.h:

Guida pratica a#iPhone SDK

82

1 2 3 4 5 6 7 8 9 10 11 12

#import <UIKit/UIKit.h> #import <Foundation/Foundation.h> @class MainView; @interface VistaDue : UIView { IBOutlet MainView *mainView; } - (IBAction)tornaAvistaUno; @end

Anche in questo caso abbiamo solo completato lintestazione di tale classe. Adesso andiamo a scrivere il codice relativo a tutti i metodi che ci servono, e che non abbiamo ancora implementato. Iniziamo dal le VistaDue.m, in cui delegheremo ancora lazione alla classe MainView, proprio come abbiamo fatto in precedenza:
1 2 3 4 5 6 7 8 9 10 #import "VistaDue.h" #import "MainView.h" @implementation VistaDue - (IBAction)tornaAvistaUno { [mainView tornaAvistaUno]; } @end

Tutto come abbiamo gi visto per VistaUno. Ora giunto il momento di impostare la classe MainView, e tutti i metodi che gli abbiamo delegato. Apriamo il le MainView.h e completiamo la dichiarazione della classe nel seguente modo:

Guida pratica a#iPhone SDK

83

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

#import <UIKit/UIKit.h> #import <Foundation/Foundation.h> @class VistaUno; @class VistaDue; @interface MainView : UIView { IBOutlet VistaUno *vistaUno; IBOutlet VistaDue *vistaDue; } -(IBAction)vaiAsecondaView; -(IBAction)tornaAvistaUno; @end

Anche in questo caso non abbiamo fatto niente di particolare. Possiamo notare che abbiamo denito le due viste (righe 8 e 9), e le due azioni (righe 12 e 13), che ora dobbiamo implementare. Apriamo il le MainView.m e scriviamo il seguente codice:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #import "MainView.h" @implementation MainView -(void)awakeFromNib{ [self addSubview:vistaUno]; } -(IBAction)vaiAsecondaView{ [vistaUno removeFromSuperview]; [self addSubview:vistaDue]; } -(IBAction)tornaAvistaUno{ [vistaDue removeFromSuperview]; [self addSubview:vistaUno]; } @end

Finalmente abbiamo denito i due metodi che si occupano della gestione delle viste. Potete vedere che sono praticamente uguali: prima rimuovono la vista presente (righe 10 e 15) e poi aggiungono quella nuova da visualizzare (righe 11 e 16). Abbiamo quasi concluso! Salviamo tutti i le (io consiglio sempre di eseguire un Build) e torniamo in Interface Builder, aprendo il le MainWindow.xib. Nel Connections Inspector della vista principale (la MainView) dovreste vedere lultimo elemento che non abbiamo an-

Guida pratica a#iPhone SDK

84

cora collegato, ovvero la vistaDue: colleghiamola con la seconda vista, proprio come abbiamo gi fatto in precedenza con la vistaUno. Il risultato di tale operazione sar il seguente:

Ora abbiamo davvero nito! Salviamo tutto, chiudiamo Interface Builder e da XCode selezioniamo Build and Go!. Godetevi la vostra applicazione funzionante!

Guida pratica a#iPhone SDK

85

Potrebbero piacerti anche