IOS 6 forza l’orientamento del dispositivo al paesaggio

Ho dato un’app con dire 10 view controller. Io uso il controller di navigazione per caricarli / scaricarli.

Tutti tranne uno sono in modalità verticale. Supponiamo che il settimo VC sia in orizzontale. Ho bisogno che venga presentato in orizzontale quando viene caricato.

Si prega di suggerire un modo per forzare l’orientamento a passare da verticale a orizzontale in IOS 6 (e sarà bello lavorare anche su IOS 5).

Ecco come lo stavo PRIMA di IOS 6:

- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; UIViewController *c = [[[UIViewController alloc]init] autorelease]; [self presentModalViewController:c animated:NO]; [self dismissModalViewControllerAnimated:NO]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{ return (interfaceOrientation == UIInterfaceOrientationPortrait); } 

Presentare e respingere un VC modale costringeva l’app a rivedere il suo orientamento, quindi shouldAutorotateToInterfaceOrientation stato necessario richiamareAutorotateToInterfaceOrientation.

Quello che ho provato in IOS 6:

 - (BOOL)shouldAutorotate{ return YES; } -(NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskLandscape; } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{ return UIInterfaceOrientationLandscapeLeft; } 

Al carico, il controller rimane in verticale. Dopo aver ruotato il dispositivo, l’orientamento cambia solo ok. Ma ho bisogno di far ruotare automaticamente il controller in orizzontale sul carico, quindi l’utente dovrà ruotare il dispositivo per vedere i dati correttamente.

Un altro problema: dopo aver ruotato il dispositivo di nuovo in UIInterfaceOrientationMaskLandscape , l’orientamento passa a UIInterfaceOrientationMaskLandscape , anche se ho specificato in UIInterfaceOrientationMaskLandscape solo UIInterfaceOrientationMaskLandscape . Perché succede?

Inoltre, NONE di cui sopra 3 metodi vengono chiamati.

Alcuni dati (utili):

  1. Nel mio file plist ho specificato 3 orientamenti – tutti ma al contrario.
  2. Il progetto è stato avviato in Xcode 4.3 IOS 5. Tutte le classi incluse le xibs sono state create prima di Xcode 4.5 IOS 6, ora utilizzo l’ultima versione.
  3. Nel file plist la barra di stato è impostata su visibile.
  4. Nel file xib (quello che voglio essere in orizzontale) la barra di stato è “Nessuno”, l’orientamento è impostato su orizzontale.

Qualsiasi aiuto è apprezzato. Grazie.

Ok, gente, posterò la mia soluzione.

Ciò che ho:

  1. Un’applicazione basata sulla vista, con diversi controller di vista. (Era basato sulla navigazione, ma dovevo renderlo basato sulla vista, a causa di problemi di orientamento).
  2. Tutti i controller di visualizzazione sono verticali, tranne uno – landscapeLeft.

Compiti:

  1. Uno dei miei controller di vista deve ruotare automaticamente in orizzontale, indipendentemente da come l’utente trattiene il dispositivo. Tutti gli altri controller devono essere ritratti e dopo aver lasciato il controller orizzontale, l’app deve forzare la rotazione in verticale, indipendentemente dal modo in cui l’utente mantiene il dispositivo.
  2. Questo deve funzionare come su IOS 6.x come su IOS 5.x.

Partire!

( Aggiornamento Rimosso le macro suggerite da @Ivan Vučica)

In tutti i tuoi controller di visualizzazione di PORTRAIT si annullano i metodi di autorotazione come questo:

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{ return (toInterfaceOrientation == UIInterfaceOrientationPortrait); } -(BOOL)shouldAutorotate { return YES; } - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } 

Puoi vedere i 2 approcci: uno per IOS 5 e un altro per IOS 6.

Lo stesso vale per il tuo controller di visualizzazione LANDSCAPE, con alcune aggiunte e modifiche:

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{ [image_signature setImage:[self resizeImage:image_signature.image]]; return (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft); } -(BOOL)shouldAutorotate { return YES; } - (NSUInteger)supportedInterfaceOrientations { [image_signature setImage:[self resizeImage:image_signature.image]]; return UIInterfaceOrientationMaskLandscapeLeft; } 

ATTENZIONE : per forzare l’autorotazione in IOS 5 è necessario aggiungere questo:

 - (void)viewDidLoad{ [super viewDidLoad]; if ([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0) [[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:NO]; } 

Analogicamente, dopo aver lasciato il controller LANDSCAPE, indipendentemente dal controller che si carica, è necessario forzare nuovamente l'autorotazione per IOS 5, ma ora si utilizzerà UIDeviceOrientationPortrait mentre si passa a un controller PORTRAIT:

 - (void)viewDidLoad{ [super viewDidLoad]; if ([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0) [[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationPortrait animated:NO]; } 

Ora l'ultima cosa (ed è un po 'strano) - devi cambiare il modo in cui passi da un controller a un altro, a seconda dell'IOS:

Crea una class NSObject "Schalter" ("Switch" dal tedesco).

In Schalter.h dì:

 #import  @interface Schalter : NSObject + (void)loadController:(UIViewController*)VControllerToLoad andRelease:(UIViewController*)VControllerToRelease; @end 

In Schalter.m dì:

 #import "Schalter.h" #import "AppDelegate.h" @implementation Schalter + (void)loadController:(UIViewController*)VControllerToLoad andRelease:(UIViewController*)VControllerToRelease{ //adjust the frame of the new controller CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame]; CGRect windowFrame = [[UIScreen mainScreen] bounds]; CGRect firstViewFrame = CGRectMake(statusBarFrame.origin.x, statusBarFrame.size.height, windowFrame.size.width, windowFrame.size.height - statusBarFrame.size.height); VControllerToLoad.view.frame = firstViewFrame; //check version and go if (IOS_OLDER_THAN_6) [((AppDelegate*)[UIApplication sharedApplication].delegate).window addSubview:VControllerToLoad.view]; else [((AppDelegate*)[UIApplication sharedApplication].delegate).window setRootViewController:VControllerToLoad]; //kill the previous view controller [VControllerToRelease.view removeFromSuperview]; } @end 

ORA, questo è il modo in cui usi Schalter (supponiamo che tu vada dal controller Warehouse al controller Prodotti):

 #import "Warehouse.h" #import "Products.h" @implementation Warehouse Products *instance_to_products; - (void)goToProducts{ instance_to_products = [[Products alloc] init]; [Schalter loadController:instance_to_products andRelease:self]; } bla-bla-bla your methods @end 

Ovviamente è necessario rilasciare l'object instance_to_products :

 - (void)dealloc{ [instance_to_products release]; [super dealloc]; } 

Bene, è questo. Non esitare a downvotare, non mi interessa. Questo è per quelli che sono alla ricerca di soluzioni, non per la reputazione. Saluti! Sava Mazare.

Questo dovrebbe funzionare, è simile alla versione pre-iOS 6, ma con un UINavigationController :

 UIViewController *portraitViewController = [[UIViewController alloc] init]; UINavigationController* nc = [[UINavigationController alloc] initWithRootViewController:portraitViewController]; [self.navigationController presentModalViewController:nc animated:NO]; [self.navigationController dismissModalViewControllerAnimated:NO]; 

Lo chiamo prima di spingere il prossimo UIViewController . UIViewController il successivo UIViewController spinto a essere visualizzato in modalità Ritratto anche se l’attuale UIViewController è in UIViewController (dovrebbe funzionare anche per Verticale in UIViewController ). Funziona su iOS 4 + 5 + 6 per me.

Penso che la soluzione migliore sia quella di attenersi alla documentazione ufficiale di Apple. Quindi, secondo questo, io uso i seguenti metodi e tutto funziona molto bene su iOS 5 e 6. Nel mio VC sovrascrivo i seguenti metodi:

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return UIInterfaceOrientationIsPortrait(interfaceOrientation); } 

Metodi per iOS 6, il primo metodo restituisce la maschera di orientamento supportata (come indica il loro nome)

 -(NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskPortrait; } 

la seconda è quella che dice al tuo VC quale è l’orientamento preferito per l’interfaccia quando VC sta per essere visualizzato.

 - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return UIInterfaceOrientationPortrait; } 

Basta cambiare Portrait per l’orientamento che desideri;) Questa soluzione funziona senza problemi, non mi piace l’idea di creare macro e altre cose, che aggira questa semplice soluzione. Spero che questo aiuto …

Ho avuto lo stesso problema, 27 visualizzazioni nella mia applicazione, di cui 26 in verticale e solo uno in tutti gli orientamenti (un visualizzatore di immagini :)). Aggiungendo la macro su ogni class e sostituendo la navigazione non era una soluzione che mi sentivo a mio agio con …

Quindi, volevo mantenere la meccanica di UINavigationController nella mia app e non sostituirla con altri codici.

Cosa fare:

@ 1 Nell’applicazione delegato nel metodo didFinishLaunchingWithOptions

 if ([[UIDevice currentDevice].systemVersion floatValue] < 6.0) { // how the view was configured before IOS6 [self.window addSubview: navigationController.view]; [self.window makeKeyAndVisible]; } else { // this is the code that will start the interface to rotate once again [self.window setRootViewController: self.navigationController]; } 

@ 2 Poiché il controller di navigazione risponderà solo con YES per l'autorotazione, è necessario aggiungere alcune limitazioni: Estendere UINavicationController -> YourNavigationController e collegarlo a Interface Builder.

@ 3 Ignora i "nuovi metodi anoying" dal controller di navigazione.

Poiché questa class è personalizzata solo per questa applicazione, può assumersi la responsabilità dei suoi controllori e rispondere al loro posto.

 -(BOOL)shouldAutorotate { if ([self.viewControllers firstObject] == YourObject) { return YES; } return NO; } - (NSUInteger)supportedInterfaceOrientations { if ([self.viewControllers firstObject] == YourObject) { return UIINterfaceOrientationMaskLandscape; } return UIInterfaceOrientationMaskPortrait; } 

Spero che questo ti possa aiutare

Dalle note di rilascio di iOS 6 :

Ora, i contenitori iOS (come UINavigationController) non consultano i propri figli per determinare se devono eseguire l’autorotazione.

rootViewController trasferisce il messaggio shouldAutoRotate nella gerarchia ViewController al tuo VC?

Ho usato lo stesso metodo di OP pre-ios6 (presente e congedo un VC modale) per mostrare un singolo controller di visualizzazione in modalità orizzontale (tutti gli altri in verticale). Si è rotto in iOS6 con il panorama VC che mostra in verticale.

Per risolvere il problema, ho aggiunto il metodo preferitoInterfaceOrientationForPresentation nel panorama VC. Sembra funzionare bene per OS 5 e OS 6 ora.

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft); } - (BOOL)shouldAutorotate { return NO; } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return UIInterfaceOrientationLandscapeLeft; } 

Ehi ragazzi dopo aver trionfato un sacco di diverse soluzioni possibili senza successo sono uscito con la seguente soluzione spero che aiuti !.

Ho preparato una ricetta :).

Problema: è necessario modificare l’orientamento dei viewcontrollers usando navigationcontroller in ios 6.

Soluzione:

navigazione suggerita

passo 1. un UIviewcontroler iniziale per innescare i passaggi modali per il landscape e il ritratto di UInavigationControllers come mostra l’immagine ….

più profondamente in UIViewController1 abbiamo bisogno di 2 azioni segues secondo la variabile globale in Appdelegate ….

 -(void)viewDidAppear:(BOOL)animated{ if([globalDelegate changeOrientation]==0){ [self performSegueWithIdentifier:@"p" sender:self]; } else{ [self performSegueWithIdentifier:@"l" sender:self]; } } 

anche noi abbiamo bisogno di tornare al ritratto e | paesaggio….

 - (IBAction)dimis:(id)sender { [globalDelegate setChangeOrientation:0]; [self dismissViewControllerAnimated:NO completion:nil]; } 

passo 2. il primo Pushed UiViewControllers su ogni NavigationController va con …

 -(NSUInteger)supportedInterfaceOrientations{ return [self.navigationController supportedInterfaceOrientations]; } -(BOOL)shouldAutorotate{ return YES; } 

passaggio 3. Sovrascriviamo il metodo supportatoInterfaceOrientations nella sottoclass di UInavigationController ….

nel tuo customNavigationController abbiamo …..

 -(NSUInteger)supportedInterfaceOrientations{ if([self.visibleViewController isKindOfClass:[ViewController2 class]]){ return UIInterfaceOrientationMaskPortrait; } else{ return UIInterfaceOrientationMaskLandscape; } } 

passaggio 4. Nello storyboard o in base al codice, impostare wantFullScreenLayout flag su yes, su entrambi i registri di controllo dell’udinea e del panorama.

Prova a seguire un UINavigationController che usa una categoria o è sottoclass per specificare l’orientamento desiderato, quindi passa al VC desiderato. Leggi di più qui .

In alternativa puoi fare lo stesso usando i blocchi:

 UIViewController *viewController = [[UIViewController alloc] init]; viewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; [self presentViewController:viewController animated:NO completion:^{ [self dismissViewControllerAnimated:NO completion:nil]; }]; 

Inoltre, chiamalo prima di premere la nuova vista.

Vai al tuo file Info.plist e apporta la modifica inserisci la descrizione dell'immagine qui

Ho avuto lo stesso problema. Se vuoi forzare la visualizzazione di un particolare controller della vista in orizzontale, fallo prima di inserirlo nella pila di navigazione.

 UIInterfaceOrientation currentOrientation = [[UIApplication sharedApplication] statusBarOrientation]; if (currentOrientation == UIInterfaceOrientationPortrait || currentOrientation == UIInterfaceOrientationPortraitUpsideDown) [[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeLeft]; UIViewController *vc = [[UIViewController alloc] init]; [self.navigationController pushViewController:vc animated:YES]; [vc release]; 

L’ho risolto sottoclassando UINavigationController e sovrascrivendo le interfacce supportate di navigazione come segue:

 - (NSUInteger)supportedInterfaceOrientations { return [[self topViewController] supportedInterfaceOrientations]; } 

Tutti i controller implementati supportano InterfacciaOrientamenti con i loro orientamenti desiderati.

Ho usato la seguente soluzione. Nel controller a una vista che ha un orientamento diverso da tutti gli altri, ho aggiunto un controllo di orientamento nel metodo prepareForSegue . Se il controller della vista di destinazione necessita di un diverso orientamento dell’interfaccia visualizzato, viene inviato un messaggio che forza l’interfaccia a ruotare durante la sequenza.

 #import  

 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if(UIDeviceOrientationIsLandscape(self.interfaceOrientation)) { UIInterfaceOrientation destinationOrientation; if ([[segue destinationViewController] isKindOfClass:[UINavigationController class]]) { UINavigationController *navController = (UINavigationController *)[segue destinationViewController]; destinationOrientation = [navController.topViewController preferredInterfaceOrientationForPresentation]; } else { destinationOrientation = [[segue destinationViewController] preferredInterfaceOrientationForPresentation]; } if ( destinationOrientation == UIInterfaceOrientationPortrait ) { if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) { objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationPortrait ); } } } }