2012-09-13 17 views
36

Ho riscontrato questo problema con l'SDK di iOS 6: sto avendo alcune viste che dovrebbero essere abilitate a ruotare (ad esempio una videoview), e alcune che non lo sono. Ora capisco che devo controllare tutti gli orientamenti nell'Info.plist dell'app e quindi ordinare in ogni ViewController, cosa dovrebbe accadere. Ma non funziona! L'app ruota sempre sugli orientamenti, che sono indicati nel file Info.plist.Rotazioni di iOS 6: supportatoInterfaceOrientations non funziona?

Info.plist:

<key>UISupportedInterfaceOrientations</key> 
    <array> 
     <string>UIInterfaceOrientationPortrait</string> 
     <string>UIInterfaceOrientationLandscapeLeft</string> 
     <string>UIInterfaceOrientationLandscapeRight</string> 
    </array> 

qualsiasi ViewController che shouldnt essere consentito di ruotare:

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

- (NSUInteger)supportedInterfaceOrientations{ 
return UIInterfaceOrientationMaskPortrait; 
} 

Osservazione: App ruota al paesaggio e orientamento verticale. Qualche idea del perché o di quello che sto facendo male?

Cheers, Marc

Edit: I miei ultimi risultati indicano anche, che se si vuole avere la rotazione ad un certo punto della tua applicazione, è avete per attivare tutte e quattro le direzioni di rotazione nelle impostazioni del tuo progetto o Info .plist. Un'alternativa a questo è di ignorare

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

nel vostro AppDelegate, che sostituisce l'Info.plist. Non è più possibile impostare solo Portrait in Info.plist e quindi avere la rotazione in alcuni ViewController ignorando shouldAutorotateToInterfaceOrientation o supportInterfaceOrientations.

+0

Questo è sotto NDA, post nei forum di Apple Dev e posso aiutare. –

+0

È meglio così? Immagino che ora a nessuno importerebbe più di danneggiare NDA ... – stk

+0

è ancora un NDA, anche io direi che questo è un problema comune ed è stato pienamente risposto nei forum di sviluppo già – wattson12

risposta

31

Se ViewController è figlio di UINavigationController o UITabBarController, è il genitore il problema. Potrebbe essere necessario creare una sottoclasse che controller della vista genitore, semplicemente ignorando quei metodi InterfaceOrientation come hai mostrato la tua domanda

EDIT:

Esempio per il ritratto solo TabBarController

  @interface MyTabBarController : UITabBarController 
      { 
      } 
      @end 

      @implementation MyTabBarController 

      // put your shouldAutorotateToInterfaceOrientation and other overrides here   
      - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
       return (interfaceOrientation == UIInterfaceOrientationPortrait); 
      } 

      - (NSUInteger)supportedInterfaceOrientations{ 
       return UIInterfaceOrientationMaskPortrait; 
      } 

     @end 
+4

e non dovresti dimenticare il metodo - supportedInterfaceOrientations, perché in iOS6, shouldAutorotate ... non è più usato! – stk

-2

Come opzione alternativa, nel caso in cui desideri preservare la funzionalità di rotazione pre-iOS6 nella tua app:

Ecco un po 'di codice utile su github che fa girare il metodo per iOS6 in modo che la rotazione funzioni come su iOS4/iOS4. Questo mi ha davvero aiutato, perché sto supportando un'app legacy che gestisce realmente le sue rotazioni. Sarebbe stato molto lavoro implementare le modifiche richieste per iOS6. Complimenti per l'utente che lo ha pubblicato.

https://gist.github.com/3725118

+1

Questa è una pessima idea. Basta dire. – steipete

27

aggiunta alla risposta di CSmith sopra, il seguente codice in una sottoclasse UINavigationController permette delega al top controller della vista nel modo in cui mi aspettavo far funzionare tutto questo, in primo luogo:

- (BOOL)shouldAutorotate; 
{ 
    return YES; 
} 

- (NSUInteger)supportedInterfaceOrientations 
{ 
    if ([[self topViewController] respondsToSelector:@selector(supportedInterfaceOrientations)]) 
     return [[self topViewController] supportedInterfaceOrientations]; 
    else 
     return [super supportedInterfaceOrientations]; 
} 
+5

Funziona perfettamente !! e perché questo non è fatto da Apple IOS SDK? :( – flypig

+5

@flypig, Lo era già. L'SDK di Apple iOS si è comportato esattamente come questo in precedenza.Essi hanno cambiato il nuovo sistema senza alcun motivo apparente con iOS 6. –

8

Ecco un'altra alternativa all'approccio di CSmith.

Se si desidera replicare il pre-iOS 6 comportamento in cui tutti i punti di vista nello stack di navigazione/barra delle schede devono accordarsi su un insieme ammissibile di orientamenti, mettere questo nella vostra sottoclasse di UITabBarController o UINavigationController:

- (NSUInteger)supportedInterfaceOrientations 
{ 
    NSUInteger orientations = [super supportedInterfaceOrientations]; 

    for (UIViewController *controller in self.viewControllers) 
     orientations = orientations & [controller supportedInterfaceOrientations]; 

    return orientations; 
} 
2

tenta di aggiungere questa categoria:

@interface UINavigationController(InterfaceOrientation) 

@end 

@implementation UINavigationController(InterfaceOrientation) 

- (NSUInteger) supportedInterfaceOrientations { 
    if (self.viewControllers.count > 0) 
     return [[self.viewControllers objectAtIndex:0] supportedInterfaceOrientations]; 
    else 
     return UIInterfaceOrientationMaskAll; 
} 

@end 
+0

Funziona alla grande, qualsiasi sottoclasse! Grazie! Ma io preferisco usare ultimo controller della vista nell'array, che al momento viene visualizzato. – HotJard

-1
risposta di

@Shimanski Artem è buona, ma credo che utilizzando il controller più in alto (attualmente visibile) è una soluzione migliore:

012.
@interface UINavigationController(InterfaceOrientation) 

@end 

@implementation UINavigationController(InterfaceOrientation) 

- (NSUInteger) supportedInterfaceOrientations { 
    if (self.viewControllers.count > 0){ 
     return [[self.viewControllers objectAtIndex:[self.viewControllers count] - 1] supportedInterfaceOrientations]; 
    } 
    return UIInterfaceOrientationMaskAll; 
} 

@end 
0

Ulteriore aggiunta a @CSmith e @EvanSchoenberg.

Se si dispone di alcune viste che ruotano e alcune viste che non lo sono, è necessario creare un'istanza personalizzata di UITabBarController, lasciando tuttavia decidere ciascuna UIViewController.

- (BOOL)shouldAutorotate; 
{ 
    return YES; 
} 

- (NSUInteger)supportedInterfaceOrientations 
{ 
    UIViewController * top; 
    UIViewController * tab = self.selectedViewController; 
    if([tab isKindOfClass: 
     ([UINavigationController class])]) { 
     top = [((UINavigationController *)tab) 
       topViewController]; 
    } 

    if ([top respondsToSelector:@selector(supportedInterfaceOrientations)]) 
     return [top supportedInterfaceOrientations]; 
    else 
     return [super supportedInterfaceOrientations]; 
} 
0

Per le persone che utilizzano UINavigationController e Swift, è possibile aggiungere questa estensione al progetto. Successivamente, i controller di navigazione delegano il controllo al proprio controller figlio.

extension UINavigationController { 
    override public func supportedInterfaceOrientations() 
    -> UIInterfaceOrientationMask { 
     if let ctrl = topViewController { 
      return ctrl.supportedInterfaceOrientations() 
     } 
     return super.supportedInterfaceOrientations() 
    } 

    override public func shouldAutorotate() -> Bool { 
     if let ctrl = topViewController { 
      return ctrl.shouldAutorotate() 
     } 
     return super.shouldAutorotate() 
    } 
} 
Problemi correlati