• Programmazione Android
  • CORSI ONLINE
  • Web Agency

Logo

Corsi di programmazione web e mobile online
Navigation
  • Home
  • CORSI ONLINE
  • Tutorial Pratici
  • GUIDE COMPLETE
    • Corso completo di C
    • Corso videogame con Cocos2d
    • Programmazione Cocoa Touch
  • Sezioni
    • Libri e manuali
    • Tips & Tricks
    • Risorse utili
    • Strumenti di Sviluppo
    • Materiale OpenSource
    • Framework
    • Guide Teoriche
    • Guide varie
    • Grafica e Design
    • iPad
    • News
    • Video Tutorial
    • Windows Phone
  • Pubblicità
  • About
    • Chi siamo
    • Pubblicazioni
    • Collabora
    • Sostieni devAPP

T#083 – Aggiungiamo funzionalità agli oggetti: Le categorie

By Costantino Pistagna | on 28 Dicembre 2010 | 2 Comments
Senza categoria

t083-Categories-objective-c-xcode-Icon Alcune volte è necessario presentare un oggetto generico che eredita da UIView in maniera esclusiva sullo schermo, per richiamare l’attenzione o semplicemente per mostrare una scelta “obbligata” all’utente. UIKit di Cocoa, ci mette a disposizione la classe UIAlertView proprio per questo scopo. Purtroppo, il suo funzionamento è molto restrittivo in termini di personalizzazione da parte dell’utente e come funzionalità offerte.
In quest’articolo, sfrutteremo questa esigenza per prendere confidenza con una tecnica di programmazione molto particolare di Objective-C: Le categorie.


bn_auto-e-moto-rubate-app-iphone

Introduzione alle categorie

Le categorie sono un potente strumento, fornito agli sviluppatori Objective-C, per estendere le funzionalità degli oggetti messi a disposizione del programmatore. A differenza delle sottoclassi, permettono di specializzare il comportamento di un oggetto senza dover scendere in dettagli tecnici relativi alla classe stessa. Una categoria permette di estendere immediatamente il comportamento di una determinata classe; l’estensione sarà immediatamente disponibile in tutte le classi (e sottoclassi) che ereditano dall’oggetto di cui stiamo estendendo le funzionalità.

Come in Javascript con l’estensione dei metodi, le categorie permettono al programmatore di aggiungere funzionalità al codice di una classe, senza per questo esserne gli sviluppatori originali e/o in possesso del codice sorgente. In linea di principio, è possibile estendere il comportamento di una classe/oggetto, semplicemente creando una categoria per questo scopo. A differenza del concetto di sottoclasse, le categorie possono essere cumulative, nel senso che più categorie possono essere sommate per aggiungere funzionalità diverse alla stessa classe. Quindi, una classe può essere estesa contemporaneamente da più categorie che, insieme, concorrono a fornire nuove caratteristiche all’oggetto base.
Per creare una categoria è necessario implementare una porzione di codice dichiarativo (header file .h) ed una porzione di codice implementativo (implementation file .m). Il nostro file di header, quindi, conterrà un prologo dichiarativo su quello che stiamo per fare; in pratica, informeremo il compilatore che stiamo per estendere la classe UIView, ad esempio, con delle nuove funzionalità (metodi d’istanza). Conseguentemente, il file di implementazione conterrà l’implementazione di questi metodi e delle funzionalità dichiarate in precedenza.

Nuove funzionalità per le UIView

Ogni oggetto che eredita da UIView può essere aggiunto, a sua volta, come subview all’interno di un’altro oggetto UIView padre, attraverso l’uso del metodo d’istanza: -(void)addSubview:
Il nostro obiettivo è quello di aggiungere una specializzazione a questo comportamento per presentare il nuovo oggetto in maniera gradevole, ad esempio mostrandolo come pop-up al centro dello schermo e rendendolo reattivo al tocco dell’utente. Alla pressione su di esso, infatti, vorremmo che scompaia in maniera altrettanto “gradevole” dallo schermo. La figura sotto, illustra il concetto che stiamo per realizzare programmaticamente.


t083-Aggiungiamo-funzionalita-agli-oggetti-Le-categorie-objective-c-xcode

Visto che non abbiamo ancora chiaro da “quale” classe erediteremo per il nostro oggetto modale da presentare o, semplicemente, se vogliamo dotare “tutti” gli oggetti che ereditano da UIView di queste caratteristiche, utilizzeremo una categoria. Quest’ultima estenderà il comportamento di tutti gli oggetti che ereditano da UIView, in maniera istantanea, con due nuovi metodi:

-(void) pushViewTo:(UIView *)aView;
-(void)removeFromView;

Il primo metodo si occuperà di mostrare il nostro oggetto all’interno del contenitore padre passato come parametro. Il secondo metodo, si preoccuperà di rimuoverlo dal contenitore padre e distruggerlo dalla memoria. La parte di dichiarazione, che andrà nel file di hedear (.h), sarà così composta:

@interface UIView (animation)

-(void) pushViewTo:(UIView *)aView;
-(void)removeFromView;

@end

I metodi dichiarati sono gli unici pubblici e, quindi, gli unici che verranno esposti a tutte le classi estese dalla categoria. La prima riga ci dice che stiamo estendendo la classe UIView, creando una categoria chiamata animation. Le successive due righe, racchiuse prima della parola chiave @end, indicano i metodi che creeremo nell’apposito file d’implementazione.
A differenza delle normali dichiarazioni di interfacce di classe, qui non è possibile dichiarare delle variabili di istanza. L’unica cosa che possiamo fare è dichiarare i metodi che popoleranno la nostra categoria e che andranno ad estendere il comportamento standard della classe. La parte implementativa (.m) sarà costituita di conseguenza:

@implementation UIView (animation) 

-(void) pushViewTo:(UIView *)aView {
	…
	…
}

-(void)removeFromView {
	…
	…
}

@end

Popoliamo i nostri metodi

A questo punto resta da implementare il codice per ognuno dei metodi sopra. In quest’esempio, vogliamo che l’oggetto UIView, compaia dal centro dell’oggetto padre e si ingrandisca gradualmente, con un effetto molla:

-(void) pushViewTo:(UIView *)aView {
	//Creiamo una matrice di trasformazione che scala la dimensione originale a zero
	CGAffineTransform transform = CGAffineTransformMakeScale(0.1, 0.1);
	self.transform = transform;

	//Abilitiamo l'interazione utente sull'oggetto
	self.userInteractionEnabled = YES;

	//Aggiungiamo l'oggetto al padre (aView) e posizioniamolo al centro
	[aView addSubview:self];
	self.center = CGPointMake(160, 240);

	//Iniziamo un contesto CoreAnimation
	[UIView beginAnimations:@"pushViewToScreen" context:nil];
	[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
	[UIView setAnimationDuration:0.3];

	//Impostiamo come delegato la categoria stessa!
	[UIView setAnimationDelegate:self];
	
	//Al completamento della prima parte dell'animazione, lanciamo la seconda.
	[UIView setAnimationDidStopSelector:@selector(pushViewToSecondPart)];

	// Tutto il codice racchiuso nel contesto d'animazione verrà automaticamente
	// animato con keyframes.
	CGAffineTransform transform2 = CGAffineTransformMakeScale(1.1, 1.1);
	self.transform = transform2;

	[UIView commitAnimations];
}

Resta da implementare il metodo di scomparsa dallo schermo: -(voi)removeFromView. Per ottenere un simpatico effetto molla, dobbiamo “spezzare” l’animazione in tre fasi distinte: ingradimento, rimpicciolimento, scomparsa.

-(void)removeFromView {
	[UIView beginAnimations:@"removeFromView" context:nil];
	[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
	[UIView setAnimationDuration:0.3];
	[UIView setAnimationDelegate:self];
	[UIView setAnimationDidStopSelector:@selector(removeFromViewSecondPart)];
	CGAffineTransform transform2 = CGAffineTransformMakeScale(1.1, 1.1);
	self.transform = transform2;
	[UIView commitAnimations];
	
}

-(void)removeFromViewSecondPart {
	[UIView beginAnimations:@"removeFromViewSecondPart" context:nil];
	[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
	[UIView setAnimationDuration:0.3];
	[UIView setAnimationDelegate:self];
	[UIView setAnimationDidStopSelector:@selector(removeFromViewThirdPart)];
	CGAffineTransform transform2 = CGAffineTransformMakeScale(0.1, 0.1);
	self.transform = transform2;
	[UIView commitAnimations];
}	

-(void)removeFromViewThirdPart {
	[self removeFromSuperview];
}

Ancora una cosa: Il controllo del tocco. Categorie e delegati

Resta da implementare un’ultima caratteristica. L’oggetto presentato a schermo dovrebbe rispondere al tocco dell’utente, reagendo con la scomporsa / rimozione di se stesso. Questo ci offre un utile spunto per illustrare un’interessante caratteristica delle categorie.
Le categorie, come una normale classe, possono implementare metodi delegati rendendoli disponibili a tutte le classi (o sottoclassi) che stiamo estendendo. Categorie e delegati, quindi, possono coesistere ed insieme possono collaborare nell’estendere il comportamento di una classe. Nel nostro caso specifico, implementeremo all’interno della categoria un metodo delegato per la gestione del tocco utente:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

Ci basterà verificare che il tocco sia stato effettuato sull’oggetto stesso (self) ed, in caso affermativo, lanciare il metodo di rimozione dallo schermo definito sopra:

#pragma mark UITouch events
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    if (touch.view == self)
        [self removeFromView];
}

A questo punto, il nostro oggetto UIView è stato specializzato con una categoria animation che ne rende l’apparizione e la scomparsa dallo schermo molto gradevole. Visto che abbiamo esteso il comportamento della classe UIView, qualunque altro oggetto che eredita da UIView, potrà usare i nostri nuovi metodi di apparizione e scomparsa. Ad esempio, un oggetto UIImageView le potrà sfruttare a suo vantaggio per mostrare un’immagine a schermo. Nel codice d’esempio fornito troverete due esempi, uno con UIView ed uno con UIImageView. Entrambi gli oggetti ereditano le stesse primitive.
L’uso delle categorie non si ferma solo a questo ma, avere ben chiaro qual’e’ lo scopo principale per cui è stato pensato questo pattern di programmazione, renderà più semplice l’apprendimento di tecniche avanzate d’uso.

Non mi resta che salutarvi e ringraziarvi per l’attenzione. Buone feste e felice anno nuovo!

Costantino Pistagna


Se avete problemi con il tutorial, questo è il nostro file di progetto.


bn_auto-e-moto-rubate-app-iphone

Share this story:
  • tweet

Tags: addSubviewbeginAnimationscategorieCGAffineTransformCoreAnimationCostantino PistagnasetAnimationtouchesBeganTutorial Praticiuiview

Recent Posts

  • Parte il percorso programmatori iOS in Swift su devACADEMY.it

    20 Dicembre 2017 - 0 Comment
  • Android, crittografare dati velocemente con Encryption

    24 Settembre 2018 - 0 Comment
  • Sql2o, accesso immediato ai database tramite Java

    3 Settembre 2018 - 0 Comment
  • Okio, libreria per ottimizzare l’input/output in Java

    27 Agosto 2018 - 0 Comment

Related Posts

  • 7. Creiamo una semplice calcolatrice in XCode e Objective-C (parte 3)

    24 Ottobre 2011 - 1 Comment
  • 6. Creiamo una semplice calcolatrice in XCode e Objective-C (parte 2)

    27 Settembre 2011 - 2 Comments
  • 5. Creiamo una semplice calcolatrice in XCode e Objective-C (parte 1)

    19 Settembre 2011 - 6 Comments

Author Description

2 Responses to “T#083 – Aggiungiamo funzionalità agli oggetti: Le categorie”

  1. 31 Dicembre 2010

    iPhoneInside

    Articolo interessante !
    Dato che si parla di gestione del touch, mi sapreste aiutare con un piccolo problemino?

    Nella mia applicazione creo un numero di UIImageView e ne memorizo il puntatore in un array.

    Nell’evento “touchesBegan”, come faccio a sapere quale immagina è stata “toccata” ?
    Con cosa devo confrontare “touch.view” ?

    Grazie 🙂

  2. 4 Gennaio 2011

    Etha

    Se dai un’occhiata all’ultimo pezzo di codice dell’articolo, c’è scritto proprio ciò che ti serve. 😉
    …
    UITouch *touch = [touches anyObject];
    if (touch.view == self) {
    //doSomething
    }

Leave a Reply

Your email address will not be published. Required fields are marked *


*
*

Corso online di programmazione android e java

SEZIONI

  • Android
  • Comunicazioni
  • Contest
  • Corsi ed Eventi
  • Corso completo di C
  • Corso programmazione videogiochi
  • Framework
  • Grafica e Design
  • Guida rapida alla programmazione Cocoa Touch
  • Guide Teoriche
  • Guide varie
  • iPad
  • Le nostre applicazioni
  • Libri e manuali
  • Materiale OpenSource
  • News
  • Pillole di C++
  • Progetti completi
  • Risorse utili
  • Strumenti di Sviluppo
  • Swift
  • Tips & Tricks
  • Tutorial Pratici
  • Video Tutorial
  • Windows Phone

Siti Amici

  • Adrirobot
  • Allmobileworld
  • Apple Notizie
  • Apple Tribù
  • Avvocato360
  • Blog informatico 360°
  • bubi devs
  • fotogriPhone
  • GiovaTech
  • iApp-Mac
  • iOS Developer Program
  • iPodMania
  • MelaRumors
  • Meritocracy
  • SoloTablet
  • TecnoUser
  • Privacy & Cookie Policy
©2009-2018 devAPP - All Rights Reserved | Contattaci
devAPP.it è un progetto di DEVAPP S.R.L. - Web & Mobile Agency di Torino
Str. Volpiano, 54 - 10040 Leini (TO) - C.F. e P.IVA 11263180017 - REA TO1199665 - Cap. Soc. € 10.000,00 i.v.

devACADEMY.it

Vuoi imparare a programmare?

Iscriviti e accedi a TUTTI i corsi con un’unica iscrizione.
Oltre 70 corsi e migliaia di videolezioni online e in italiano a tua disposizione.

ISCRIVITI SUBITO