Massimo Oliviero

I deliri digitali di un programmatore informatico e aspirante fotografo…
luglio 28th, 2011 by Massimo

iPhone come forzare l’interface orientation (landscape o portrait)

In certe occasioni è indispensabile forzare l’interface orientation di una view. Pensiamo ad una applicazione che voglia visualizzare un contenuto e che questo contenuto sia fruibile solo in landscape. Normalmente l’utente parte da una posizione portrait (verticale) del device. Si vuole che all’entrata di una certa view l’orientation si sposti in landscape in modo automatico anche se il device è ancora in posizione verticale. Bene non esiste una metodo ufficiale per questa attività. Esistono però due soluzioni alternative valide, ognuna con i suoi pro e i suoi contro e sono:

  1. Utilizzare una proprietà non documentata della classe UIDevice
  2. Gestire manualmente la rotazione di tutti gli elementi grafici
Il primo approccio è molto semplice e consiste in una semplice riga di codice:
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
Pur essendo una soluzione molto semplice e compatta presenta una serie di rischi:
  1. Genera un warning  in compilazione in quanto non è una funzione esposta dall’SDK
  2. Non è garantito che funzioni con le versioni future dell’SDK proprio perché non è ufficialmente supportata
Il secondo approccio prevede la gestione manuale della rotazione di tutti gli elementi, in questo modo:
- (void)viewWillAppear:(BOOL)animated
{
    UIScreen *screen = [UIScreen mainScreen];
    CGFloat screenWidth = screen.bounds.size.width;
    CGFloat screenHeight = screen.bounds.size.height;
 
    UIAccelerationValue x = self.navigationController.navigationBar.frame.origin.x;
    UIAccelerationValue y = self.navigationController.navigationBar.frame.origin.y;
 
    [UIView beginAnimations:@"orientation" context:nil];
    [UIView setAnimationDuration:0.5f];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
 
    self.navigationController.view.transform = CGAffineTransformIdentity;
    self.navigationController.view.transform = CGAffineTransformMakeRotation(M_PI_2);
    self.navigationController.view.frame = CGRectMake(0.0f, 0.0f, 320.0f, 480.0f);
    self.navigationController.view.center = CGPointMake(screenWidth/2.0, screenHeight/2.0);
    self.navigationController.navigationBar.frame = CGRectMake(x, y, 480, 32);
 
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
    [UIView commitAnimations];
}
 
- (void)viewWillDisappear:(BOOL)animated
{
    UIScreen *screen = [UIScreen mainScreen];
    CGFloat screenWidth = screen.bounds.size.width;
    CGFloat screenHeight = screen.bounds.size.height;
 
    UIAccelerationValue x = self.navigationController.navigationBar.frame.origin.x;
    UIAccelerationValue y = self.navigationController.navigationBar.frame.origin.y;
 
    [UIView beginAnimations:@"orientation" context:nil];
    [UIView setAnimationDuration:0.5f];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    self.navigationController.view.transform = CGAffineTransformIdentity;
    self.navigationController.view.transform = CGAffineTransformMakeRotation(M_PI * 2);
    self.navigationController.view.bounds = CGRectMake(0.0f, 0.0f, 320.0f, 480.0f);
    self.navigationController.view.center = CGPointMake(screenWidth/2.0, screenHeight/2.0);
    [self.navigationController.navigationBar setFrame:CGRectMake(x, y, 320, 44)];
 
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:YES];
    [UIView commitAnimations];
}
In pratica viene applicata una rotazione di 90° sul NavigationController (che contiene tutti gli elementi) in entrata e una trasformazione inversa in uscita. Da notare che la NavigationBar presenta due dimensioni diverse se è in landscape (32 px) o in portrait (44 px). Questa soluzione risulta compatibile anche con le versioni future dell’SDK però presenta i seguenti problemi:
  1. C’è un leggero difetto grafico in fase di rotazione se la NavigationBar contiene elementi al suo interno come button o immagini. In pratica c’è un leggero sfarfallio degli elementi che si adattano alla nuova dimensione della NavigationBar. Non mi è ancora chiaro questo problema.
  2. E’ sicuramente più lento di una soluzione nativa
A voi la scelta.

Lascia un Commento

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *

*

È possibile utilizzare questi tag ed attributi XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">