Animare il cambiamento di una vista

Questa tecnica è utilizzabile sia per creare dissolvenze in uno slideshow di UIImage che per animare la variazione di UI in una UIView.

1
2
3
4
5
6
7
8
/* qui il codice che modifica la vista */
 
CATransition *transition = [CATransition animation];
transition.duration = 1.0f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
 
[aView.layer addAnimation:transition forKey:nil];
/* qui il codice che modifica la vista */

CATransition *transition = [CATransition animation];
transition.duration = 1.0f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;

[aView.layer addAnimation:transition forKey:nil];

Si può aggiungere un .subtype, ad esempio se si vuole far scorrere la vista e decidere la direzione:

1
2
3
4
5
CATransition *transition = [CATransition animation];
transition.duration = .2f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromLeft;
CATransition *transition = [CATransition animation];
transition.duration = .2f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromLeft;

(fonte)

YouTube player integrato nell’app

Se si vogliono integrare video tratti da YoutTube nella propria app senza però rinunciare alla flessibilità e alla coerenza grafica di una UIView (quindi scartando l’ipotesi di una UIWebView), allora si può ricorrere ad una sottoclasse della UIView che visualizza video di YouTube usando un MPMoviePlayerController.

Si può usare quindi il progetto Open Source LBYouTube di larcus94 che è distribuito sotto licenza MIT ed è disponibile in github.

La sottoclasse è molto semplice da usare perché basta aggiungerla al progetto e usarla come in questo esempio (prelevato dalla pagina github e corretto):

1
2
3
4
5
6
7
LBYouTubePlayerController* controller = [[LBYouTubePlayerController alloc] initWithYouTubeURL:[NSURL URLWithString:@"http://www.youtube.com/watch?v=1fTIhC1WSew&list=FLEYfH4kbq85W_CiOTuSjf8w&feature=mh_lolz"] quality:LBYouTubeVideoQualityLarge];
 
controller.delegate = self;
controller.view.frame = CGRectMake(0.0f, 0.0f, 200.0f, 200.0f);
controller.view.center = self.view.center;
 
[self.view addSubview:self.controller.view];
LBYouTubePlayerController* controller = [[LBYouTubePlayerController alloc] initWithYouTubeURL:[NSURL URLWithString:@"http://www.youtube.com/watch?v=1fTIhC1WSew&list=FLEYfH4kbq85W_CiOTuSjf8w&feature=mh_lolz"] quality:LBYouTubeVideoQualityLarge];

controller.delegate = self;
controller.view.frame = CGRectMake(0.0f, 0.0f, 200.0f, 200.0f);
controller.view.center = self.view.center;

[self.view addSubview:self.controller.view];

Tip: mostrare da codice una navigationBar in una UITableViewController

Spesso capita di creare da codice un UITableViewController, ad esempio per caricarlo da popover o per mostrarlo come vista modale. Quando lo presentiamo, però, se vogliamo che la tabella abbia una navigationBar possiamo quella già incorporata nel Navigation Controller. Quest’ultimo, se contiene un UIViewController, permette l’accesso dal controller alla navigationBar.

Ecco come costruire la struttura:

 

1
2
3
4
MyTableViewController *tableViewController = [[MyTableViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tableViewController];
 
[self presentModalViewController:navController animated:YES];
MyTableViewController *tableViewController = [[MyTableViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tableViewController];

[self presentModalViewController:navController animated:YES];

ricordiamo quindi di creare prima il controller della tabella e dopo quello del navigation controller, avendo cura di indicare proprio la tabella come root.

Includere a posteriori una View in un UINavigationController

Può capitare di aver creato un UIViewController di prova e doverlo poi includere in una struttura di navigazione come un UINavigationController. Per non dover creare un nuovo progetto da template e includere i file già implementati, si può creare la struttura in pochi semplici passaggi.

Innanzitutto creiamo un RootViewController (comprensivo di file xib), ovver la vista che sarà quella principale dell’intera struttura.

Poi scriviamo nel AppDelegate.h il seguente codice:

1
2
3
4
5
6
7
8
9
#import <UIKit/UIKit.h>
 
@interface TNAAppDelegate : UIResponder <UIApplicationDelegate>
 
@property (strong, nonatomic) UIWindow *window;
 
@property (strong, nonatomic) UINavigationController *navigationController;
 
@end
#import <UIKit/UIKit.h>

@interface TNAAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) UINavigationController *navigationController;

@end

e nell’AppDelegate.m dovrà esserci il seguente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#import "AppDelegate.h"
 
#import "RootViewController.h"
 
@implementation AppDelegate
 
@synthesize window = _window;
@synthesize navigationController=_navigationController;
 
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
 
    RootViewController *rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil];
    self.navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
    self.window.rootViewController = self.navigationController;
    [self.window makeKeyAndVisible];
    return YES;
}
#import "AppDelegate.h"

#import "RootViewController.h"

@implementation AppDelegate

@synthesize window = _window;
@synthesize navigationController=_navigationController;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.

    RootViewController *rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil];
    self.navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
    self.window.rootViewController = self.navigationController;
    [self.window makeKeyAndVisible];
    return YES;
}

In questo modo viene creato via codice il navigationController con già caricato il primo viewController. Da questo basterà, tramite ad esempio il tocco di un pulsante o di una riga di tabella, fare un push alla view che volevamo includere nella struttura.

Semplici animazioni nelle UIView

Per animare uno o più oggetti in una UIView è sufficiente seguire questo schema di massima:

1
2
3
4
5
6
7
8
9
10
// proprietà di partenza
 
[UIView beginAnimations:@"NomeAnimazione" context:nil];
[UIView setAnimationDuration:4.5];
[UIView setAnimationDelay:1.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
 
// proprietà di arrivo
 
[UIView commitAnimations];
// proprietà di partenza

[UIView beginAnimations:@"NomeAnimazione" context:nil];
[UIView setAnimationDuration:4.5];
[UIView setAnimationDelay:1.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

// proprietà di arrivo

[UIView commitAnimations];

Ad esempio potremmo far spostare un oggetto cambiando il valore oggetto.frame.origin.x all’interno del blocco Animations, ma possiamo anche far apparire o scomparire degli oggetti regolandone la proprietà alpha.

Nell’esempio l’animazione dura 4.5 secondi, parte con un ritardo di 1 secondo, e segue una delle quattro curve d’animazione disponibili che ne regola la velocità lungo il percorso.