17

Ho un'app per iPhone che sto aggiornando a iOS 6 che sta avendo problemi di rotazione. Ho un UITabBarController con 16 UINavigationCotrollers. La maggior parte delle visualizzazioni secondarie può funzionare in verticale o orizzontale ma alcune sono solo verticali. Con iOS 6 le cose ruotano quando non dovrebbero.iOS 6 UITabBarController orientamento supportato con controller UINavigation corrente

ho provato sottoclasse il tabBarController di restituire il supportedInterfaceOrienations della corrente del navigationController selezionato viewController:

- (NSUInteger)supportedInterfaceOrientations{ 

    UINavigationController *navController = (UINavigationController *)self.selectedViewController; 
    return [navController.visibleViewController supportedInterfaceOrientations]; 
} 

Questo mi ha fatto più vicino. Il controller della vista non ruoterà fuori posizione quando è visibile, ma se sono in orizzontale e cambio le schede la nuova scheda sarà in orizzontale anche se non è supportata.

Idealmente l'app si troverà solo nell'orientamento supportato dell'attuale controller di visualizzazione visibile. Qualche idea?

risposta

58

sottoclasse tuoi UITabBarController imperativi questi metodi:

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    // You do not need this method if you are not supporting earlier iOS Versions 
    return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation]; 
} 

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

-(BOOL)shouldAutorotate 
{ 
    return YES; 
} 

sottoclasse tuoi UINavigationController imperativi seguenti metodi:

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

-(BOOL)shouldAutorotate 
{ 
    return YES; 
} 

quindi implementare questi metodi nei vostri viewControllers che non si desidera ruotare:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 

-(BOOL)shouldAutorotate 
{ 
    return NO; 
} 

-(NSUInteger)supportedInterfaceOrientations 
{ 
    return UIInterfaceOrientationMaskPortrait; 
} 

E per viewControllers che non da ruotare:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
    { 
     return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 
    } 

    -(NSUInteger)supportedInterfaceOrientations 
    { 
     return UIInterfaceOrientationMaskAllButUpsideDown; 
    } 

    -(BOOL)shouldAutorotate 
    { 
     return YES; 
    } 

tuo tabbarController deve essere aggiunto come il RootViewController della finestra dell'applicazione. Se si prevede di supportare gli orientamenti predefiniti, tutti tranne upssideown è l'impostazione predefinita per iPhone, quindi non è necessario fare altro. Se si desidera supportare sottosopra o se non si desidera supportare un altro degli orientamenti, è necessario impostare i valori appropriati in delegato app e/o info.plist.

+7

Questo è quasi funzionante per me. Il problema è che se sono già in modalità orizzontale quando passo a un tab il ritratto è ancora visibile in orizzontale. Il ritratto rotante lo fissa e non ritorna in posizione orizzontale, ma ho ancora bisogno che sia in verticale quando viene caricato per la prima volta. – Ryan

+0

Non sono sicuro di cosa sia esattamente necessario ruotare, ma scommetto che lo farai - (vuoto) viewWillLayoutSubviews. Potrei non avere esattamente ragione su quel nome di metodo dalla memoria. I miei punti di vista, dove ho usato questo codice, stanno cambiando completamente quando ruotato e uso questo metodo per riconfigurarli in modalità verticale. Puoi anche provare qualcosa in -viewWillDisappear. Forse [self.view setNeedsDisplay]. Al momento non sono in Xcode quindi queste sono solo idee che vorrei esplorare nel tuo caso. –

+0

Bello! Funziona come un fascino! – Dennso

5

Ho riscontrato che alcuni controller Vista nello stack di spostamento supportano tutti gli orientamenti, alcuni solo di tipo portrait, ma UINavigationController restituiva tutti gli orientamenti supportati dall'app, questo piccolo ha aiutato me. Non sono sicuro se questo è destinato comportamento o quello

@implementation UINavigationController (iOS6OrientationFix) 

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

@end 
+0

non lo faccio capire in che modo questo hack ti ha aiutato ad avere comportamenti diversi sul controller di diverse visualizzazioni di un controller di navigazione.Perché so che questo hack verrà eseguito solo una volta, quindi tutti i controller di visualizzazione avranno lo stesso comportamento di rotazione di topViewController. Hing ?? –

+1

questo codice viene eseguito ogni volta che il dispositivo cambia orientamento, quindi questo restituirà gli orientamenti supportati per i quali mai uiviewcontroller è attualmente attivo e visibile al momento – Mindaugas

+0

funziona perfettamente. Grazie –

3

penso che sia meglio qualcosa di simile (come metodo di categoria)

-(NSUInteger) supportedInterfaceOrientations { 
    if([self.topViewController respondsToSelector:@selector(supportedInterfaceOrientations)]) 
    { 
     return [self.topViewController supportedInterfaceOrientations]; 
    } 
    return UIInterfaceOrientationMaskPortrait; 
} 

Questo assicura che il metodo è implementato. Se non stai facendo questo controllo e il metodo non è implementato (come in iOS5 env) l'app dovrebbe bloccarsi!

0

Se si prevede di abilitare o disabilitare la rotazione per tutti i controller di vista, non è necessario creare sottoclasse UINavigationController. utilizzare invece:

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 

nel vostro AppDelegate.

Se si prevede di supportare tutti gli orientamenti della tua app, ma diversi orientamenti su CAPOGRUPPO View Controller (UINavigationController pila per esempio) si dovrebbe usare

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 

da AppDelegate in combinazione con i metodi descritti di un genitore View Controller .

- (BOOL)shouldAutorotate 

e

- (NSUInteger)supportedInterfaceOrientations 

Ma se si prevede di avere differenti impostazioni di orientamento nei bambini diversi ViewControllers nello stesso stack di spostamento (come me) è necessario controllare la ViewController corrente nella pila di navigazione.

ho creato il seguente nel mio UINavigationController sottoclasse:

- (BOOL)shouldAutorotate 
{ 
    return YES; 
} 

- (NSUInteger)supportedInterfaceOrientations 
{ 
    int interfaceOrientation = 0; 

    if (self.viewControllers.count > 0) 
    { 
     DLog(@"%@", self.viewControllers); 
     for (id viewController in self.viewControllers) 
     { 
      if ([viewController isKindOfClass:([InitialUseViewController class])]) 
      { 
       interfaceOrientation = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; 
      } 
      else if ([viewController isKindOfClass:([MainViewController class])]) 
      { 
       interfaceOrientation = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; 
      } 
      else 
      { 
       interfaceOrientation = UIInterfaceOrientationMaskAllButUpsideDown; 
      } 
     } 
    } 
    return interfaceOrientation; 
} 

Dal momento che non si può controllare più da bambini ViewControllers le impostazioni di rotazione del controller di vista presentato si deve in qualche modo intercettare ciò controller di vista è attualmente nello stack di navigazione . Quindi è quello che ho fatto :). Spero possa aiutare !

Problemi correlati