17

Ich habe eine iPhone app Ich aktualisiere auf iOS 6, die Rotationsprobleme hat. Ich habe eine UITabBarController mit 16 UINavigationCotrollers. Die meisten Unteransichten können im Hoch- oder Querformat arbeiten, einige davon jedoch nur im Hochformat. Bei iOS 6 rotieren Dinge, wenn sie nicht sollten.iOS 6 UITabBarController unterstützt Orientierung mit aktuellen UINavigation Controller

Ich versuchte, den TabBarController Subklassen die supportedInterfaceOrienations der aktuelle Navigation der ausgewählten Viewcontroller zurückzukehren:

- (NSUInteger)supportedInterfaceOrientations{ 

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

Das hat mich näher. Der Ansichts-Controller rotiert nicht, wenn er sichtbar ist, aber wenn ich im Querformat bin und die Tabs wechsle, ist der neue Tab im Querformat, auch wenn er nicht unterstützt wird.

Idealerweise befindet sich die App nur in der unterstützten Orientierung des aktuellen sichtbaren View-Controllers. Irgendwelche Ideen?

Antwort

58

Subclass Ihre UITabBarController zwingende diese Methoden:

-(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; 
} 

Subclass Ihre UINavigationController zwingende diese Methoden:

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

-(BOOL)shouldAutorotate 
{ 
    return YES; 
} 

Dann diese Methoden in Ihrem Viewcontrollers implementieren, die Sie nicht wollen, sich drehen:

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

-(BOOL)shouldAutorotate 
{ 
    return NO; 
} 

-(NSUInteger)supportedInterfaceOrientations 
{ 
    return UIInterfaceOrientationMaskPortrait; 
} 

Und für Viewcontrollers, das Sie drehen wollen:

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

    -(NSUInteger)supportedInterfaceOrientations 
    { 
     return UIInterfaceOrientationMaskAllButUpsideDown; 
    } 

    -(BOOL)shouldAutorotate 
    { 
     return YES; 
    } 

Ihre TabBarController als RootViewController der App-Fenster hinzugefügt werden soll. Wenn Sie vorhaben, die Standardausrichtung zu unterstützen, ist die Standardeinstellung "Alles außer Upsidedown" für das iPhone nicht erforderlich. Sie müssen dann nichts anderes tun. Wenn Sie auf dem Kopf stehend unterstützen möchten oder wenn Sie eine andere Ausrichtung nicht unterstützen möchten, müssen Sie die entsprechenden Werte in App-Delegat und/oder info.plist festlegen.

+7

Das funktioniert fast für mich. Das Problem ist, wenn ich bereits in der Landschaft bin, wenn ich Registerkarten zu einem Porträt only verschiebe, ist es noch in der Landschaft. Rotierendes Hochformat fixiert es und es wird nicht zurück in die Landschaft gedreht, aber ich brauche es immer noch im Hochformat, wenn es zum ersten Mal geladen wird. – Ryan

+0

Ich bin mir nicht sicher, was genau Sie tun müssen, um es zu drehen, aber ich wette, Sie tun es in - (void) viewWillLayoutSubviews. Ich bin vielleicht nicht genau richtig mit diesem Methodennamen aus dem Speicher. Meine eigenen Ansichten, wo ich diesen Code verwendet habe, ändern sich komplett, wenn sie gedreht werden, und ich benutze diese Methode, um sie wieder in den Portrait-Modus zu versetzen. Sie könnten auch etwas in -viewWillDisappear versuchen. Vielleicht [self.view setNeedsDisplay]. Ich bin im Moment nicht bei Xcode, also sind dies nur Ideen, die ich in Ihrem Fall untersuchen würde. –

+0

Schön! Klappt wunderbar! – Dennso

5

Ich hatte Problem, dass einige View-Controller im Navigationsstack alle Orientierungen unterstützen, einige nur Porträt, aber UINavigationController gab alle App unterstützte Orientierungen zurück, dieser kleine Hack half mir. Ich bin mir nicht sicher, ob dieses Verhalten beabsichtigt ist oder was

@implementation UINavigationController (iOS6OrientationFix) 

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

@end 
+0

akzeptieren kann ich nicht Verstehst du, wie dieser Hack dir geholfen hat, verschiedene Verhaltensweisen auf verschiedenen Views Controllern eines Navigationscontrollers zu haben.Wenn ich weiß, dass dieser Hack nur einmal ausgeführt wird, haben alle View Controllerd dasselbe Rotationsverhalten wie topViewController Hing?? –

+1

Dieser Code wird jedes Mal ausgeführt, wenn das Gerät die Ausrichtung ändert. Dies gibt die unterstützten Orientierungen zurück, für die der uiviewcontroller derzeit aktiv und sichtbar ist. – Mindaugas

+0

das funktioniert großartig. Vielen Dank –

3

Ich denke, besser so ähnlich ist (als Kategorie-Methode)

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

dies stellt sicher, dass das Verfahren durchgeführt wird. Wenn du diese Überprüfung nicht machst und die Methode nicht implementiert ist (wie in iOS5 env), sollte die App abstürzen!

0

Wenn Sie die Rotation für alle View-Controller aktivieren oder deaktivieren möchten, brauchen Sie keine Unterklasse UINavigationController. Stattdessen verwenden:

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

in Ihrem AppDelegate.

Falls Sie alle Orientierungen in der App aber unterschiedliche Orientierungen auf ELTERN View-Controller unterstützen (UINavigationController Stack zum Beispiel) sollten Sie

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

von AppDelegate in Kombination mit den folgenden Methoden in der ELTERN-View-Controller verwenden .

- (BOOL)shouldAutorotate 

und

- (NSUInteger)supportedInterfaceOrientations 

Aber wenn Sie in verschiedenen CHILDREN Viewcontrollers in dem gleichen Navigationsstapel (wie ich) unterschiedliche Ausrichtung Einstellungen haben Sie die aktuellen Viewcontroller im Navigationsstapel überprüfen müssen.

Ich habe folgendes in meiner UINavigationController Unterklasse erstellt:

- (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; 
} 

Da Sie nicht mehr von Kindern Viewcontrollers müssen Sie die Rotationseinstellungen dargebotener View-Controller steuern kann irgendwie abfangen, welche View-Controller ist im Navigationsstapel . Also das habe ich gemacht :). Ich hoffe, das hilft !

Verwandte Themen