Quello che ho pensato per voi questa volta è un po’ particolare, ma secondo me molto carino e con molte cose utili all’interno da imparare. Sicuramente tutti voi conoscerete Brushes (link iTunes), un programma molto famoso per disegnare sul proprio iPhone e iPod Touch con le dita.
Ho pensato, quindi, di spiegarvi come realizzarne uno tutto vostro! In questa prima parte vedremo come fare in modo che l’utente possa, muovendo il dito sullo schermo, disegnare a suo piacimento.
Ovviamente in questa prima parte ci occuperemo solo di questo aspetto. Nel prossimo tutorial, invece, vedremo come rendere possibile la definizione di un pennello personale, con dimensione e colore a scelta.
Ora, però, concentriamoci sulla prima parte. Buon tutorial a tutti!
1. Creiamo un nuovo progetto
Iniziamo creando il progetto per la nostra applicazione. Create un nuovo progetto edi tipo “Utility Application” e inserite “SampleBrushes” come nome.
La struttura che abbiamo selezionato ci mette a disposizione due viste: una “Main View” che è quella che appare inizialmente, e una “Flipside View”, che appare se viene premuto il pulsante “i” (info), con un’animazione già definita. Queste due viste, quindi, potremo sfruttarle per creare la nostra applicazione: nella “Main View” creeremo la zona in cui l’utente potrà disegnare, mentre nella “Flipside View” inseriremo le impostazioni (quindi il colore del pennello, la dimensione, etc).
Prima di definire l’aspetto grafico della nostra applicazione, definiamo un componente che poi andremo a collegare con un elemento in Interface Builder.
Aprite, quindi, il file “MainViewController.h” (nella sottocartella “Main View) e inserite le seguenti definizioni:
#import "FlipsideViewController.h"
@interface MainViewController : UIViewController <FlipsideViewControllerDelegate> {
IBOutlet UIImageView *viewDisegno;
}
- (IBAction)showInfo;
- (IBAction)cancella;
@end
Alla riga 4 abbiamo definito un oggetto di tipo UIImageView, che sarà l’oggetto in cui l’utente disegnerà, e che visualizzerà, quindi, una serie di componenti grafiche colorate. Alla riga 10, invece, abbiamo definito un’azione, che ci servirà per cancellare tutto ciò che l’utente ha disegnato.
2. Definiamo l’aspetto grafico dell’applicazione
Salviamo il file e apriamo “MainView.xib”. Ci ritroveremo con una vista come questa:
Dobbiamo modificarne un po’ l’aspetto. Iniziamo scegliendo come colore di sfondo il bianco (lo fate semplicemente dal pannello Attributes Inspector). Cancellate, inoltre, il bottone “i” che è presente nell’angolo basso destro della vista.
Inserite, quindi, un componente di tipo “UIImageView”, in modo che occupi tutta la vista:
Aggiungete, poi, una UIToolbar sul fondo della vista stessa. Io ho messo come stile della toolbar “Black Translucent”, ovviamente voi potete farla come preferite. Inserite, inoltre, due bottoni “Bar Button Item”, e un “Flexible Space Bar Button Item” tra i due. Il primo bottone rinominatelo in “Cancella” mentre il secondo in “Settings” (Impostazioni è troppo lunga come dicitura xD). Ecco l’aspetto finale della mia applicazione:
Ovviamente sarebbe più carino inserire delle immagini nei bottoni, ma per semplicità ho inserito dei semplici nomi.
Colleghiamo, ora, l’elemento e le azioni che abbiamo definito poco fa via codice (l’azione “showInfo” era già presente di default). Dal pannello dei documenti selezioniamo “File’s Owner” e spostiamoci in “Connections Inspector”. Colleghiamo “viewDisegno” con la UIImageView che abbiamo inserito, l’azione “cancella” colleghiamola con l’omonimo pulsante, mentre “showInfo” collegatela con il bottone “Settings”. Se avrete eseguito tutto correttamente avrete un pannello delle connesioni come questo:
Abbiamo concluso questa fase. Possiamo salvare il tutto e chiudere Interface Builder.
3. Definiamo i metodi necessari
Torniamo ora al file “MainViewController.h”. Dobbiamo definire degli elementi che ci serviranno nel nostro programma. Ecco il codice da aggiungere a quello già presente:
#import "FlipsideViewController.h"
@interface MainViewController : UIViewController <FlipsideViewControllerDelegate> {
IBOutlet UIImageView *viewDisegno;
CGPoint ultimoPunto;
float dimensionePennello;
UIColor *colorePennello;
}
- (IBAction)showInfo;
- (IBAction)cancella;
@end
Analizziamo gli elementi che abbiamo appena inserito. Alla riga 6 abbiamo definito un oggetto CGPoint, che non è altro che un contenitore delle deu componenti di un punto: le coordinate x e y. Questo ci servirà per sapere il punto precedente a quello considerato, permettendoci così di tracciare una linea. Alla riga 9 e 10 definiamo le caratteristiche del pennello: dimensione e colore. La dimensione è una variabile di tipo reale (float), mentre il colore è definito dal tipo UIColor, che inizializzeremo con lo standard RGB.
Queste sono le uniche dichiarazioni di cui abbiamo bisogno. Salviamo quindi questo file e spostiamoci in “MainViewController.m”.
Le azioni che ci interessa definire saranno da implementare in 3 metodi tipici della gestione del multitouch:
- touchesBegan, richiamato quando si inizia un movimento. Dovremo ricavare il punto in cui deve iniziare il disegno;
- touchesMoved, richiamato quando un movimento è in corso. Ogni volta che viene avviato deve disegnare un segmento colorato, in modo che appaia una linea raffigurante il disegno dell’utente;
- touchesEnded, metodo richiamato quando il movimento è terminato. In particolare serve quando l’utente compie solo un singolo tap, disegnando così un semplice punto.
Iniziamo, quindi, a scrivere il codice necessario. Iniziamo con il metodo “viewDidLoad”:
- (void)viewDidLoad {
[super viewDidLoad];
dimensionePennello = 5.0;
colorePennello = [[UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0] retain];
}
Il suo compito è molto semplic e chiaro: viene impostata una dimensione standard del pennello, a 5.0 (pixel) e un colore, in questo caso il rosso. La definizione del colore avviene settando le componenti RGB, ovvero Red (rosso), Green (verde) e Blue (blu): variando le quantità con un valore compreso da 0.0 a 1.0 otterremo tutti i colori ammessi da questo sistema. Il campo alpha, invece, rappresenta la trasparenza. Fate qualche prova per prendere confidenza con questo sistema!
Il secondo metodo che andiamo a definire è “touchesBegan”. La sua implementazione è molto semplice, dobbiamo solo ricavare il punto di inizio del movimento. Ecco il metodo da inserire:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
ultimoPunto = [touch locationInView:viewDisegno];
}
Come vedete è molto semplice: dall’oggetto touch si ricava il punto (sempre definito come CGPoint), che viene assegnato all’oggetto “ultimoPunto” (riga 4). È importante specificare “viewDisegno” come parametro della funzione “locationInView”, altrimenti ricaverete tocchi relativi anche ad altre parti dello schermo, che però a noi non interessano.
Passiamo ora alla definizione del metodo più impegnativo e importante: “touchesMoved”. Ecco il metodo da inserire:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint puntoCorrente = [touch locationInView:viewDisegno];
// definiamo il contest grafico
UIGraphicsBeginImageContext(viewDisegno.frame.size);
[viewDisegno.image drawInRect:CGRectMake(0, 0, viewDisegno.frame.size.width, viewDisegno.frame.size.height)];
// settiamo la forma e la dimensione del pennello
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), dimensionePennello);
// convertiamo il colore e impostiamolo come colore del pennello
const CGFloat *components = CGColorGetComponents([colorePennello CGColor]);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), components[0], components[1], components[2], components[3]);
// disegna il percorso
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), ultimoPunto.x, ultimoPunto.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), puntoCorrente.x, puntoCorrente.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
// settiamo il disegno appena creato
viewDisegno.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
ultimoPunto = puntoCorrente;
}
Iniziamo ad analizzare passo passo il codice che abbiao appena scritto.
Alla riga 7 troviamo la definizione di un “Graphics Contexts”. Questo è un aspetto complesso del Core Graphics, ma utilizzando questa funzione lo adattiamo semplicemente alla nostra UIImageView, che infatti gli passiamo come parametro. Questo ci permetterà di disegnare all’interno della nostra immagine. Con l’istruzione seguente, infatti, definiamo l’area in cui potremo disegnare: essa avrà la stessa dimensione dell’immagine “viewDisegno”.
Le righe 10 e 11 si riferiscono alla definizione del “pennello”, con cui l’utente disegnerà sullo schermo. Prima, infatti, viene impostata la forma (in questo caso “kCGLineCapRound” è di forma circolare, ma possiamo anche farlo quadrato o triangolare, vi basta guardare la documentazione per vedere gli altri valori possibili), poi la dimensione, passando ovviamente la variabile “dimensionePennello”, che contiene proprio il valore desiderato (riga 11).
Le righe 13 e 14 servono per impostare il colore al nostro pennello. Abbiamo visto prima che il colore è definito da un elemento UIColor. Purtroppo dobbiamo convertire le varie componenti in CGFloat, e l’unico modo che ho trovato è quello che vedete nel codice. Prima convertiamo l’elemento “colorePennello” in un array di tipo CGFloat (riga 13), poi passiamo le varie componenti all’istruzione che setta il colore del pennello (riga 14).
Le righe dalla 16 alla 19 sono quelle che si occupano del disegno vero e proprio della linea. Partendo da “ultimoPunto” fino a “puntoCorrente” viene disegnato un tratto, un disegno, che comporrà poi il tratto voluto dall’utente.
Le righe 21 e 22 settano il disegno che è stato creato nell’immagine “viewDisegno”, rendendola così visibile all’utente.
Come vedete non è poi così complicato il codice, però bisogna fare attenzione a non dimenticare niente.
Manca poco per terminare il nostro programma! Dobbiamo definire il metodo “touchesEnded”. Esso dovrà esattamente fare le stesse cose che fa il metodo “touchesMoved”. Potremmo anche non implementare questo metodo, però in caso di singolo tap non succederebbe niente, mentre noi vogliamo disegnare un singolo punto. Ovviamente potete personalizzare questo aspetto, decidendo voi l’azione da compiere. Ecco il codice da inserire se volete che ad un singolo tap venga disegnato un punto:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesMoved:touches withEvent:event];
}
Come vedete non facciamo altro che richiamare il metodo “touchesMoved”, davvero semplicissimo.
L’ultima cosa da fare è l’implementazione del metodo “cancella”. Anche questo è davvero molto semplice, per cancellare tutto ciò che l’utente ha disegnato basta porre a “nil” l’immagine:
- (IBAction)cancella{
viewDisegno.image = nil;
}
Davvero semplice!
Abbiamo concluso questa prima parte del nostro tutorial! Clicchiamo “Build and Run” e testiamo il nostro personalissimo Brushes!
Se avete problemi con il tutorial, questo è il nostro file di progetto.
Nella prossima parte del tutorial vedremo come aggiungere delle impostazioni, da cui potremo modificare il colore del pennello e la sua dimensione. Alla prossima puntata!
La guida è stata creata da Andrea Busi per “devAPP”, partendo dalla guida “Drawing to the screen” del forum di “iPod Touch Fans”. I meriti, quindi, sono dei legittimi autori.















16 Responses to “T#059 – Creiamo un’applicazione per iPhone in stile “Brushes” [Parte 1]”
30 Giugno 2010
El JobsoSe invece io vorrei cancellare solo l’ultimo tratto fatto cosa devo fare?
Complimenti per il tutorial e grazie in anticipo!
30 Giugno 2010
Andrea Busibella domanda..
così come è strutturato il programma non penso sia possibile. Si dovrebbe, secondo me, salvare tutti i movimenti compiuti in una sorta di vettore, in modo da poterne annullare poi gli effetti..
È da provare 😉
30 Giugno 2010
El JobsoCapito! Andrò a riprendere il libro Sviluppare Applicazioni con iPhone SDK! 🙂 Spero di trovare una risposta; in tal caso ti scrivo un commento…
1 Luglio 2010
AndreaE se io volessi implementare il multitouch per disegnare?
Comunque ottimo tutorial, già visto grazie al PDF che ho acquistato da te tempo fà 🙂
19 Luglio 2010
Emiliociao..ottimo tutorial! lavorandoci e testandolo sul device ho notato che disegniamo tramite movimenti lenti,il tratto disegnato è tondo ed uniforme,mentre se i movimenti eseguiti vengono compiuti velocemente i tratti sono molto spigolosi! sai come poter modificare questa cosa?:)
19 Luglio 2010
Andrea Busisi, purtroppo avevo letto di questo problema nella guida originale.. come soluzione bisognerebbe gestire in maniera migliore la memoria, c’è da lavorarci un pochino però 😉
17 Agosto 2010
DanieleCiao Andrea scusami la domanda/provocazione ma è un pò che seguo il tuo lavoro, ma ad una dico una sola domanda che esca un pò fuori dai binari di una semplice traduzione di qualche guida trovata su altri siti internet (sempre onestamente citati) è possobile oppure no ?
Non la prendere cone una critica fine a se stessa, ma come una critica costruttiva per spingerti a migliorare.
23 Agosto 2010
Andrea Busiciao, accetto la tua critica ma non la condivido molto.. i miei tutorial non mi sembrano essere una “semplice traduzione di qualche guida trovata su altri siti internet”, ma sono rielaborazioni più complesse..
in quasi due anni di sviluppatore per iPhone ho risposto a non so quante domande, scrivendo codice, mandando esempi, o altro ancora..
ovviamente non posso accontentare tutti, mi piacerebbe poter approfondire ogni singola domanda degli utenti, ma non vivo di questo e non ho proprio il tempo materiale per farlo.. cerco, quindi, di sfruttare solo le più interessanti per creare tutorial o guide, che possano essere d’aiuto a tutti..
terrò comunque in considerazione le tue parole, vedrò di migliorare in futuro 😉
26 Aprile 2011
nicoil mio problema è che messi tutti i codici faccio partire l’app e non scrive niente… mi rimane lo schermo bianco.. qualche aiuto?
5 Maggio 2011
Andrea Busiricontrolla, sicuramente non hai fatto qualcosa 😉
7 Giugno 2011
Gabrielebel tutorial ma potresti spiegarmi come aggiungere altri colori?? io ho provato aggiungendo nei tratti in qui si nominano i colori e quello che li appartiene ma in questo tratto di codice: CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), components[0], components[1], components[2], components[3]); io aggiungo components[4]) togliendo la parentesi tonda a components [3] e mi da un’errore, sai perchè??
7 Giugno 2011
Ignaziocla stringa di codice da modificare è questa:
[code]
colorePennello = [[UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0] retain];
[/code]
10 Giugno 2011
cursaoCiao ragazzi, ma non si potrebbero aprire nel forum topic specifici per ciascun tutorial???
in ogni caso ho una domanda per tutti, qualcuno ha provato ad introdurre il pinch to zoom???
Ho inserito una scrollview per la gestione dello zoom, ma così facendo non mi riconosce il touch, qualche idea???
6 Agosto 2012
simonedimensionePennello = 5.0;
colorePennello = [[UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0] retain];
dove ci sta retain mi da errore :IIIII
14 Agosto 2012
Andrea BusiCiao, probabilmente stai utilizzando l’ARC (la gestione automatica della memoria), introdotto con iOS 5.
Ti basta rimuovere “retain” e tutto si sistemerà 😉
7 Aprile 2013
DevTutorial #25 – Creiamo il nostro “Brushes” personale! (parte 1) - Bubi Devs[…] Leggi il tutorial completo su devAPP […]