L’utilizzo dei gradienti e’ molto diffuso nei componenti standard di UIKit (il framework Cocoa Touch di riferimento dell’interfaccia utente in iOS) oltre che in un gran numero di applicazioni. Sarebbe bello che le API di UIKit fornissero un modo comodo per impostare i gradienti, ma attualmente non e’ cosi’, sebbene le librerie grafiche di base “Quartz” contengano supporto nativo a tale funzionalita’. In aggiunta mentre MacOSX dispone della classe NSGradient che consente di configurare dei gradienti, anche tramite curve di Bezier, questa classe non e’ disponibile all’interno di UIKit. Piuttosto su CocoaTouch, per tramite delle librerie grafiche contenute nel framework Quartz, abbiamo accesso al layer CAGradientLayer che consente di costuire dei gradienti di tipo assiale, ossia lineari lungo un asse passante per due punti (a differenza di NSGradient che consente la creazione anche di gradienti radiali o su curve di Bezier).
La soluzione in UIKit e’ piuttosto semplice e richiede la creazione di una sottoclasse di UIView e l’utilizzo del layer CAGradientLayer. Vediamo perche’.
Innanzitutto che cos’e’ un layer: il layer e’ l’elemento grafico di base usato dal sistema per il rendering grafico della view sullo schermo oltre che essere l’elemento di base per tutte le animazioni che si vedono nei dispositivi basati su iOS. Nel momento in cui una view viene creata ad essa e’ associato un layer di riferimento che verra’ utilizzato dalla view, senza possibilita’ di essere modificato. Per poter conoscere che tipo di layer si intende utilizzare, il sistema durante la creazione della view chiama il metodo di classe layerClass il cui unico compito e’ quello di indicare il nome della classe (derivata da CALayer) che dovra’ essere utilizzata per quella view. Ora dato che layerClass e’ un metodo di classe, ossia un metodo che opera su oggetti classe e non su oggetti istanza, noi non possiamo associare il layer alla nostra istanza di view semplicemente cambiando una property, ma saremo costretti a costruire una sottoclasse per la nostra vista, che chiameremo per esempio GradientView che conterra’ la seguente porzione di codice:


+(Class)layerClass {
return([CAGradientLayer class]);
}

Da questo momento in poi tutte le view di tipo GradientView verranno costruite a partire da un layer gradiente. Quel che resta da fare e’ impostare i colori e gli “stop” che costituiranno il gradiente. Supponendo allora di instanziare la view tramite Interface Builder, costruiremo il codice di inizializzazione della view nel metodo initWithCoder: nella seguente maniera, in cui abbiamo costruito un semplice gradiente tra i colori rosso e giallo:


- (id)initWithCoder:(NSCoder *)decoder {

self = [super initWithCoder:decoder];
if (self) {
// Initialization code.
[(CAGradientLayer *)self.layer setColors:[NSArray arrayWithObjects:(id)[UIColor redColor].CGColor,(id)[UIColor yellowColor].CGColor,nil]];
}
return self;
}

Si noti come si sia dovuto effettuare il casting di self.layer per evitare un warning in compilazione.
E’ ovvio che possiamo facilmente estendere il nostro codice permettendo l’impostazione programmatica dei colori, cosi’ da poterli definire in fase di instanziazione, lasciando eventualmente dei default nei metodi di inizializzazione.

Gradiente assiale