Introduzione
Supponiamo di volere dotare la nostra applicazione calcolatrice, implementata precedentemente, di una nuova funzionalita' chiamata Cambio Valuta. In particolare, quello che vorremmo ottenere e' un gadget con le stesse caratteristiche di una calcolatrice (tastierino e display) e con la funzionalita' di cambio valuta (supponiamo per semplicita' EUR->US ed US->EUR).

Per fare quanto sopradescritto, esistono svariati metodi citati dalla teoria della programmazione ad oggetti, tutti validi. Per praticita', sceglieremo di creare un nuovo oggetto (classe) UIView denominato CurrencyConverterView con tutte le caratteristiche della classe CalculatorView. Le uniche cose che cambieranno saranno i tasti operazione e la logica ad essi associata. Avremmo potuto creare una classe piu' generica e specializzarla a seconda delle evenienze (calcolatrice e cambio valuta), ma per gli scopi di questo esercizio il risutato sarebbe stato pressoche' analogo.

La dichiarazione di interfaccia della nostra nuova classe conterra' gli oggetti necessari alla corretta visualizzazione del nostro applicativo di cambio valuta. Come possiamo notare, essi sono esattamente identici a quelli gia' presenti nella classe CalculatorView. Sarebbe un ottimo esercizio, a fine lezione, pensare la stessa applicazione qui descritta in maniera che le classi CalculatorView e CurrencyConverterView siano entrambe figlie di una classe MyGadget piu' generica.

Creiamo una nuova classe (tasto Option + N) e scegliamo come template UIView class. L'interfaccia della nuova classe sara' qualcosa di questo tipo:




Per quanto riguarda la parte implementativa, dovremo modificare alcune righe nel metodo di generazione del frame initWithFrame:



In particolare, dovremo aggiungere il supporto per i nuovi bottoni di cambio valuta ed eliminare quello per la gestione delle operazioni aritmetiche.

I messaggi numberPressed: ed operationPressed, saranno cosi' composti:







Il metodo di dealloc sara' analogo a quello gia' visto per la classe CalculatorView: dovremo preoccuparci di rilasciare l'array operazioni e chiamare il messaggio di dealloc sulla classe super.






UIViewController e gestione di views multiple
Proviamo ad aggiungere il supporto per la nuova classe CurrencyConverterView, all'interno del nostro UIViewController. Per fare questo, dovremo aggiungere una forward declaration ed una dichiarazione d'oggetto nell'interfaccia:




A questo punto, ci bastera' far puntare la property self.view alla view piu' adatta al nostro scopo (CalculatorView o CurrencyConverterView). Ovviamente, entrambi gli oggetti dovranno essere correttamente istanziati, prima di poter essere assegnati.

Modificare la property self.view, significa modificre l'oggetto UIView visualizzato a schermo. A tale scopo, vedremo nelle prossime lezioni che sara' possibile multiplexare views diverse attraverso l'uso di oggetti predefiniti o attraverso l'uso di una classe customizzata ed adattata a questo scopo.

Se volessimo, invece, gestire piu' controllori di vista (UIViewControllers), all'interno della stessa applicazione?



UINavigationController e ViewControllers
UIKit mette a disposizione un oggetto standard per la gestione di UIViewControllers multiple. L'oggetto si chiama UINavigationController e possiamo immaginarlo come un'ulteriore contenitore in cui aggiungere tutti i nostri UIViewControllers.




Per potere utilizzare l'oggetto UINavigationController, dobbiamo prima creare tutti gli oggetti UIViewControllers che interverranno nella nostra applicazione.

Seguendo l'esempio del controllore di vista - CalculatorViewController - creato per gestire l'oggetto CalculatorView, scriviamo un controllore equivalente per la classe CurrencyConverterView.

Creiamo una nuova classe (Tasto Option + N) di tipo UIViewController e chiamiamola CurrencyConverterViewController. Il suo file di header (.h) avra' un aspetto simile al seguente:




La parte implementativa si occupera' di istanziare e visualizzare - loadView - l'oggetto UIView designato. La deallocazione della classe, anche in questo caso, non fara' altre operazioni oltre a quella di lanciare un messaggio di dealloc alla classe padre ( super ).




La classe CalcolatriceAppDelegate andra' modificato per ospitare i nostri nuovi oggetti appena creati. In particolare, dovremo aggiungere una forward declaration per la nuova classe controllore CurrencyConverterViewController ed una dichiarazione di interfaccia per la variabile oggetto, necessaria al corretto funzionamento della stessa.




Come si puo' notare, non viene fatto nessun riferimento esplicito agli oggetti CalculatorView e CurrencyConverterView. Essi, infatti, sono gestiti in maniera indipendente dai rispettivi controllori di vista. Il delegato non deve essere a conoscenza di questi dettagli: esso deve semplicemente istanziare e mostrare a schermo i viewControllers.



UINavigationController
Spostiamoci nella parte implementativa del delegato e vediamo come modificare il metodo didFinishLaunching:




La classe UINavigationController implementa un particolare controllore che gestisce la navigazione di contenuti gerarchici. Ad ogni livello della gerarchia di navigazione, bisognera' fornire una view appropriata e gestita da un viewcontroller. Per tutte le view visualizzate a schermo attraverso questo controllore, ad esclusione della root, verra' mostrato un pulsante di navigazione a ritroso che permette all'utente di navigare in maniera appropriata l'applicazione.




Inizializziamo questo nuovo oggetto utilizzando il metodo initWithRootViewController: e passando l'oggetto radice come controllore.

La nostra window rispecchiera' questi cambiamenti, visualizzando a schermo la property view relativa al nuovo oggetto. Visto che non abbiamo settato manualmente alcuna view, l'oggetto navigationController sfruttera' la property view relativa all'oggetto radice passato come argomento in fase di inizializzazione.

Infine, dobbiamo informare la classe CalculatorViewController della presenza di un oggetto CurrencyConverterViewController, navigabile tramite l'applicazione. Per fare questo, aggiungiamo un pulsante alla property navigationItem della sua istanza in memoria. In particolare, utilizzeremo la subproperty rightBarButtonItem.

E' possibile aggiungere due pulsanti alla sinistra e/o destra della navigation bar. Visto che lo spazio risulta molto limitato, gli unici pulsanti che bisognerebbe aggiungere sono quelli relativi alla navigazione specifica dell'applicazione.

UINavigationController crea automaticamente un nuovo oggetto UINavigationItem quando viene effettuato un accesso alla sua property navigationItem. In questo modo e' possibile assegnare nuovi oggetti alla barra, senza preoccuparsi del loro posizionamento.

Per creare un nuovo pulsante, creiamo una istanza della classe UIBarButtonItem. Questa classe ci permette di definire un titolo, uno stule ed una azione da invocare alla pressione del tasto.

UIBarButtonItem *myButton = [[[UIBarButtonItem alloc] \
          initWithTitle:@"currency" style:UIBarButtonItemStylePlain \
          target:self action:@selector(pushCurrency)] autorelease];



Quando il bottone viene premuto, il selettore viene notificato. E' necessario, quindi, scrivere un metodo appropriato per la gestione della pressione del tasto.




I due metodi sopra, invocano il metodo pushViewController: per caricare sullo stack dell'oggetto UINavigationController il nuovo viewController (e quindi, la nuova view). Il sistema, in automatico, mette in primo piano la nuova vista ed offre l'opportunita' di ritornare indietro attraverso l'uso di un bottone di navigazione sulla parte sinistra della barra. L'operazione di ritorno indietro, eliminera dallo stack l'oggetto inserito, riportando l'utente al viewController precedente.

Se si vuole eliminare un bottone esistente, in qualunque punto del nostro codice, bastera' impostare a nil la relativa property:

myCalculatorViewController.navigationItem.rightBarButtonItem = nil;



Per mantenere il bottone sulla barra di navigazione, rendendolo non attivo, bisognera' usare una property del bottone:

myButton.enabled = NO;





Riferimenti
- iPhone OS Reference Library :UINavigationController Class Reference
- Mac OS X Reference Library: iPhone Application Programming Guide
- Mac OS X Reference Library: Window and Views
- iPhone SDK Application Development - Capitolo 3



    lap1

downloads