• 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#087 – Notifiche in stile growl per le nostre applicazioni iPhone e iPad

By IgnazioC | on 1 Marzo 2011 | 6 Comments
Senza categoria

Nei nostri programmi iPhone e iPad spesso utilizziamo le classi UIAlertView e UIActionSheet per mostrare all’utente messaggi, avvisi e notifiche sullo stato del programma. Queste due classi sono ottime quando vogliamo l’intervento dell’utente, per esempio per richiedere la conferma per la cancellazione di un dato o qualcosa del genere ma ci sono altri casi in cui vogliamo soltanto mostrargli un messaggio, e per questo mettiamo nell’alertView solo il pulsante “ok”. Ecco, in questi casi le alertView e gli actionSheet pussono risultare fastidiosi se i messaggi mostrati sono tanti.
Questo problema mi si è presentato in un progetto sviluppato per l’azienda dove lavoro e mentre mi chiedevo quale soluzione alternativa potessi utilizzare mi è venuto in mente growl, il sistema di notifiche che ho installato sul mio mac.

L’idea mi è sembrata pulita ed elegante, delle piccole view semitrasparenti da mostrare in un angolo della pagina e poi far scomparire in automatico…ok, si può fare.

Il risultato finale che dovremmo ottenere è questo:


t087-devAPP-Notification-growl-like

se vi piace continuate la lettura di questo nostro articolo, se non vi piace continuate lo stesso 😛 e commentate.. 🙂

Prepariamo il nostro progetto

Per realizzare questo oggetto partiamo dal creare un nuovo file all’interno del nostro progetto, il file dovrà essere subClass di UIview e lo chiameremo “NotificationView” (.h e .m).
Per chi non sapesse come fare, vi ricordo che basta cliccare sul menù “file->new file” e scegliere “Objective-C class” dalla sezione “Cocoa Touch Class” avendo cura, però, che nella casella a discesa sia selezionato “subclass of UIView”.

Questa classe dovrà (al momento) avere almeno tre proprietà:

  • un titolo,
  • un messaggio
  • e una piccola immagine da mostrare in alto a sinistra.

Iniziamo quindi a dichiarare questi oggetti all’interno del file header. In questa occasione ho utilizzato il costrutto @property invece dei più classici getter e setter, spero non vi dispiaccia!
Visto che vogliamo avere gli angoli arrotondati ci servirà importare anche quartz, quindi aggiungiamo il framework QuartzCore. I nostri due file dovrebbero apparire in questo modo:

//file: NotoficationView.h
#import 
@interface NotificationView : UIView {
	NSString	*title;
	NSString	*message;
	UIImage	*icon;
}

@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSString *message;
@property (nonatomic, retain) UIImage  *icon;
//file:NotificationView.m
#import "NotificationView.h"

@implementation NotificationView
@synthesize title, message,icon;

- (void)dealloc {
    title = nil;
	message = nil;
	icon = nil;
	[super dealloc];
	
}

Prepariamo il nostro nuovo oggetto personalizzato

Bene, iniziamo adesso ad occuparci di come dovremo istanziare questo oggetto nel nostro codice.. mica vorremmo ogni volta dover settare il titolo, il messaggio e l’icona in tre istruzioni diverse. Vogliamo un solo metodo che, anche se lungo 300 caratteri, ci permetta di fare tutto con una sola istruzione!
Aggiungiamo quindi un inizializzatore personalizzato, io in un eccesso di fantasia l’ho chiamato:

- (id)initWithTitleMessageImage:(NSString *)atitle message:(NSString *)amessage image:(UIImage *)animage

Per prima cosa all’interno di questo metodo dobbiamo richiamare un secondo costruttore, presente di default e sul quale non facciamo nessun override:

self = [self initWithFrame:CGRectMake(768, 55  , 300, 80)];

La view ha dimensioni 300×80, ma il suo angolo superiore sinistro ha coordinate (768,55) quindi attualmente è fuori dallo schermo.
Ottenuto il riferimento a “self” passiamo ad impostare le proprietà che avevamo dichiarato:

self.title = atitle;
self.message = amessage;
self.icon = animage;		

Per le caratteristiche grafiche della notification ho preferito utilizzare dei #define nel file .h così che sia più facile eventualmente modificare questi valori. Ho scritto quindi in testa al file NotificationView.h:

#define kDefaultRectColor [UIColor blackColor]
#define kDefaultCornerRadius 10.0
#define kDefaultAlphaValue	0.7
#define kDefaultBorderWidth 2.0

così all’interno del metodo initWithTitleMessageImage ho settato l’aspetto della view tramite:

self.layer.cornerRadius = kDefaultCornerRadius;
self.backgroundColor	= kDefaultRectColor;
self.alpha			= kDefaultAlphaValue;
[self.layer setBorderColor:[[UIColor whiteColor] CGColor]];
[self.layer setBorderWidth:kDefaultBorderWidth];

Infine ho dichiarato le due label e l’oggetto UIImageView per mostrare le proprietà. Il metodo completo è questo:

- (id)initWithTitleMessageImage:(NSString *)atitle message:(NSString *)amessage image:(UIImage *)animage{
	self = [self initWithFrame:CGRectMake(768, 55  , 300, 80)];
	if (self) {
		self.title = atitle;
		self.message = amessage;
		self.icon = animage;
		
		self.layer.cornerRadius = kDefaultCornerRadius;
		self.backgroundColor	= kDefaultRectColor;
		self.alpha				= kDefaultAlphaValue;
		[self.layer setBorderColor:[[UIColor whiteColor] CGColor]];
		[self.layer setBorderWidth:kDefaultBorderWidth];
		
		//Allocazione e posionzamento della label per il titolo.
		UILabel *titleLabel;
		titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 5, 250, 35)];
		[titleLabel setFont:[UIFont boldSystemFontOfSize:18]];
		[titleLabel setBackgroundColor:[UIColor clearColor]];
		[titleLabel setTextColor:[UIColor whiteColor]];
		[titleLabel setAdjustsFontSizeToFitWidth:TRUE];
		[titleLabel setText:title];
		[self addSubview:titleLabel];
		
		
		//Allocazione e posionzamento della label per il messaggio.
		UILabel *messageLabel;
		messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 30, 250, 40)];
		[messageLabel setFont:[UIFont systemFontOfSize:16]];
		[messageLabel setBackgroundColor:[UIColor clearColor]];
		[messageLabel setTextColor:[UIColor whiteColor]];
		[messageLabel setAdjustsFontSizeToFitWidth:TRUE];
		[messageLabel setText:message];
		[self addSubview:messageLabel];
		
		//Allocazione e posizionamento della imageview.
		UIImageView *imageView;
		imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 32, 32)];
		[imageView setImage:icon];
		[self addSubview:imageView];
		[imageView release];
	}
	return self;
}

Perfetto, adesso non ci resta che occuparci dell’animazione.



Le animazioni di entrata e uscita delle nostre notifiche

Io ho previsto tre stili di animazione:

  • lo slide da destra
  • lo slide da sinistra
  • il fading

Il concetto alla base è identico per tutti e tre gli stili, quindi commenterò in questo articolo solo il primo, potete provare da voi a completare il resto e se proprio non riuscite (ma sforzatevi ^^) trovate tutto il codice nel progetto allegato.

L’idea di base è che abbiamo tre eventi successivi, l’apparizione della notifica, la sua scomparsa ed il tempo che resterà ferma e visibile. Dichiariamo anche in questo caso tre #define nel file .h per la durata in secondi di questi eventi:

#define kDefaultShowAnimationDuration .7
#define kDefaultShowTime 1
#define kDefaultDismissAnimationDuration .7

Il metodo che si occupa di far apparire la view da destra è il seguente:

- (void)showFromRight {
	CGRect endREct;
	endREct = CGRectMake(768 - 300 + 10, 55, 300, 80);
	[UIView beginAnimations:nil context:nil];
	[UIView setAnimationDuration:kDefaultShowAnimationDuration];
	[UIView setAnimationDelegate:self];
	[UIView setAnimationDidStopSelector:@selector(endRightAnimation)];
	self.frame = endREct;
	[delegate notificationViewWillAppear:self];
	[UIView commitAnimations];
}

In questo codice abbiamo dichiarato un rettangolo dove dovrà apparire la notifica (768 – 300 + 10 serve per ricordarmi che la view non appare tutta, ma lascio 10 px fuori dallo schermo).
Con il metodo setAnimationDidStopSelector definiamo che alla fine dell’animazione verrà invocato il metodo endRightAnimation.

Il metodo endRightAnimation viene invocato quando la view è appena arrivata in posizione, quindi dovremmo attendere un certo lasso di tempo e poi far ritornare la view fuori dallo schermo. Io ho ottenuto questo risultato così facendo:

- (void)endRightAnimation {
	[self performSelector:@selector(dismissFromRight) withObject:self afterDelay:kDefaultShowTime];
}

- (void)dismissFromRight {
	CGRect endREct;
	endREct = CGRectMake(768 , 55 , 300, 80);
	[UIView beginAnimations:nil context:nil];
	[UIView setAnimationDuration:kDefaultDismissAnimationDuration];
	[UIView setAnimationDelegate:self];
	[UIView setAnimationDidStopSelector:@selector(remove)];
	self.frame = endREct;
	[UIView commitAnimations];
}

In pratica all’interno del metodo endRightAnimation non faccio altro che invocare il metodo performSelector dopo un delay di “kDefaultShowTime” secondi. In questo modo la view resterà visibile per questo lasso di tempo. Allo scadere del tempo viene invocato il metodo dismissFromRight che si occupa di far tornare la view nella posizione originale (fuori dallo schermo).
Per maggiore pulizia ho fatto in modo che alla fine di questa animazione venga invocato il metodo remove:

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

NOTA: Se avete avuto difficoltà a seguire qualche passaggio consultate il file del progetto allegato.

Usiamo le notifiche in stile growl nelle nostre applicazioni iPhone e iPad

In qualunque parte della nostra applicazione, se vogliamo far apparire una notifica, non dovremo far altro che scrivere:

NotificationView *n;
	n = [[NotificationView alloc] initWithTitleMessageImage:@"Mail"
													message:@"You have new email"
													  image:[UIImage imageNamed:@"AlertICON.png"]];
	[n setDelegate:self];
	[self.view addSubview:n];
		[n showFromRight];

Una chicca per i più smaliziati

Come possiamo fare ad essere avvisati quando la notifica sta per apparire e quando invece viene dismessa?
In pratica vorremmo ricreare quello che accade con le UIAlertView, in cui settando la nostra classe come suo delegate riusciamo ad intercettarne tutti gli eventi.
Ok, inventiamoci il NotificationViewDelegateProtocol e definiamo che debba avere questi due metodi:

@protocol NotificationViewDelegateProtocol

- (void)notificationViewDidDismiss:(NotificationView *)alertView;
- (void)notificationViewWillAppear:(NotificationView *)alertView;

@end

(Il mio precedente articolo parla proprio del costrutto @protocol leggetelo se avete difficoltà e non capite di cosa stiamo parlando ;))
Modifichiamo quindi la classe NotificationView aggiungendo tra le sue proprietà anche un oggetto che implementi tale protocollo:

@interface NotificationView : UIView {
	NSString	*title;
	NSString	*message;
	UIImage	*icon;
	id  delegate;
}

e modifichiamo i metodi showFromRight e remove aggiungendo l’invocazione di tali metodi del delegate:

- (void)showFromRight {
	CGRect endREct;
	endREct = CGRectMake(768 - 300 + 10, 55, 300, 80);
	[UIView beginAnimations:nil context:nil];
	[UIView setAnimationDuration:kDefaultShowAnimationDuration];
	[UIView setAnimationDelegate:self];
	[UIView setAnimationDidStopSelector:@selector(endRightAnimation)];
	self.frame = endREct;
	[delegate notificationViewWillAppear:self];
	[UIView commitAnimations];
}
- (void)remove {
	[self removeFromSuperview];
	[delegate notificationViewDidDismiss:self];
}

In questo modo la classe che vorrà fare da delegate alle nostre NotificationView potrà dichiararlo nel file di implementazione tramite:

;

ed utilizzare i due metodi per intercettare gli eventi della NotificationView:

#pragma mark -
#pragma mark NotificationViewDelegateProtocol Methods

-(void)notificationViewWillAppear:(NotificationView *)notificationView {
	NSLog(@"La notificationView dal titolo: \"%@\" sta per apparire",[notificationView title]);
}

-(void)notificationViewDidDismiss:(NotificationView *)notificationView {
	NSLog(@"La notification dal titolo: \"%@\" è stata dismessa",[notificationView title]);

}

Problemi noti

Il codice che ho scritto è sicuramente migliorabile.
Due modifiche sono sicuramente più urgenti di altre (se volete collaborare possiamo organizzarci e mettere su goolecode o altre piattaforme). La prima riguarda la lunghezza del messaggio, che in questo caso è molto limitata perchè la view non si ridimensiona automaticamente (non l’abbiamo previsto :P). La seconda, riguarda invece l’apparizione di più view contemporaneamente: se provate a farne apparire più di una, infatti, noterete un effetto fastidioso e sicuramente non voluto: le notifiche vengono sovrapposte, quindi il risultato non è ottimale.

Quindi.. sviluppatori di tutto il mondo.. unitevi.. e miglioriamo insieme questo progetto 😀

Alla prossima!


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



Share this story:
  • tweet

Tags: Ignazio CalònotificationView iPhonenotifiche growl iPhonenotifiche iPadnotifiche iPhoneTutorial Pratici

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

  • iSketch: la lavagna magica di Ignazio Calò disponibile GRATUITAMENTE in App Store

    29 Agosto 2011 - 2 Comments
  • 17. La gestione dei file in C

    22 Agosto 2011 - 4 Comments
  • Uno sguardo a Unit test: impariamo a prevenire ore e ore di debug durante lo sviluppo di Applicazioni iOS

    8 Agosto 2011 - 2 Comments

Author Description

6 Responses to “T#087 – Notifiche in stile growl per le nostre applicazioni iPhone e iPad”

  1. 1 Marzo 2011

    Junior B.

    progetto interessante, io ho creato una cosa molto simile, ma per iPhone e l’ho chiamata InfoBar… ci sarà anche nel progetto completo 🙂

    Se metti il codice su github posso aiutarti, qualche idea la ho già 😉

  2. 1 Marzo 2011

    ignazioc

    ovviamente si, purtroppo non sono pratico di questi sistemi di condivisione del codice 🙁 manda pure una mail a ignazioc at gmail.com

  3. 24 Aprile 2011

    Ze

    ciao ignazio.come mai il compilatore mi da errore se cerco di accedere alle proprietà dell oggetto self.layer??

  4. 24 Aprile 2011

    Ignazioc

    probabilmente non hai importato il framework quartz.

  5. 24 Aprile 2011

    Ze

    Si Ignazio ,grazie mille.Chissà per quanti giorni avrei sbattuto la testa sul muro in cerca di una soluzione:) grazie ancora.Luca

  6. 23 Settembre 2013

    Fabio

    Ciao Ignazio Grazie tante per questa splendida risorsa… Utile e carinissima… Ti volevo chiedere… ma se volessi aggiungere un UIActivityIndicator al posto dell’Immagine? ho provato varie cose ma non sono riuscito… magari mi perdo da qualche parte…

    Grazie Tante

    Fabio

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