2013-03-08 3 views
8

Ich habe folgende View-Controller eingerichtet:In iOS6, Probleme zwingen Viewcontroller auf bestimmte interfaceOrientation wenn auf Stapel geschoben

viewController1 Lage drehen, den Kopf frei zu einem beliebigen Ausrichtung außer Porträt.

ViewController2 wird über ViewController1 geschoben, und ich möchte, dass es die gleiche Ausrichtung ViewController1 ist und ich möchte, dass es nicht in der Lage zu drehen ist.

viewController3 wird über viewController2 geschoben. Ich möchte, dass viewController3 im Hochformat ist.

Ich habe eine Menge Probleme versucht, dies in iOS6 zu erreichen (noch nicht in iOS5 versucht). Zunächst einmal habe ich erstellt bereits eine eigene Navigation Controller und setzen folgendes drin:

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation 
{ 
    return [self.topViewController preferredInterfaceOrientationForPresentation]; 
} 

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

- (BOOL) shouldAutorotate 
{ 
    return [self.topViewController shouldAutorotate]; 
} 

Ich habe versucht, viele verschiedene Kombinationen dieser Dinge nützen zu wissen. Vor allem, wo ich Probleme habe, zwinge ich vc3 dazu, als Porträt dargestellt zu werden, wenn vc2 im Querformat ist. Jede Hilfe wäre willkommen.

Antwort

12

Was Sie hier versuchen, ist die Bekämpfung des Rahmens. Was Sie beschreiben, ist einfach nicht, wie eine Navigations-Controller-Architektur in iOS 6 funktioniert. Wenn Sie die View-Controller-Ansicht anzeigen und die Rotation erzwingen möchten, verwenden Sie einen präsentierten View-Controller. Das ist das einzige Mal, preferredInterfaceOrientationForPresentation ist sinnvoll, und Ihr View-Controller supportedInterfaceOrientations wird tatsächlich konsultiert werden, da, präsentiert wird, wird es an der Wurzel der Schnittstelle sein.

+1

Sie also überprüfe ich meine muss es als modalview schieben, um seine Rotation zu erzwingen? Ich kann es nicht auf den Navigationsstapel schieben und erzwingen? –

+2

Ja, genau, außer wie du es gesagt hast: du musst es * als * präsentieren, was früher Modal View-Controller genannt wurde, * drücke * es nicht auf einen Navigations-Stack. Ein dargestellter View-Controller kann eine Rotation erzwingen. Ein View-Controller, der auf einen Navigations-Stack geschoben wird, kann nicht; Die App kann dynamisch entscheiden, wie sie reagieren soll, wenn der * Benutzer das Gerät dreht *, aber das bloße Drücken des View-Controllers auf den Navigationsstapel führt nicht zum Rotieren der App-Oberfläche. – matt

+0

Wissen Sie zufällig, ob es eine manuelle Möglichkeit gibt, den View Controller nach der Darstellung zu drehen? Wie anstelle des Benutzers, um es zu drehen, ihm zu sagen, sich selbst zu drehen? –

5

Ich habe in einer anderen Antwort erklärt, dass es nicht unterstützt wird, in iOS 6, Kraft Rotation, wenn Sie eine neue Ansicht Controller auf eine Navigationssteuerung schieben. Sie können Regeln über kompensierende Rotation (d. H. Was sollte passieren, wenn der Benutzer das Gerät dreht), aber Sie können zwingen die Schnittstelle zu drehen. Die einzige Situation, in der iOS 6 Sie gerne force Rotation dreht, ist beim Präsentieren oder Ablehnen eines View-Controllers (presentViewController:animated: und dismissViewControllerAnimated:).

Es ist jedoch möglich, einen präsentierten View-Controller so zu verwenden, dass er wie aussieht wie Sie auf den Navigationscontroller drücken. Ich habe einen Film gemacht zu zeigen, was ich meine:

http://youtu.be/O76d6FhPXlE

Nun, das ist nicht ganz perfekt mit allen Mitteln. Es gibt keine Rotationsanimation der Statusleiste und es gibt eine Art schwarzes "Blinken" zwischen den beiden Ansichten - was beabsichtigt ist, weil es da ist, um zu verdecken, was wirklich geht. Was wirklich los ist ist, dass es wirklich zwei Differenznavigations-Controller und drei View-Controller gibt, wie in diesem Screenshot des Storyboards gezeigt.

enter image description here

Was wir haben, ist:

  • ein nav-Controller Unterklasse im Hochformat und seine Wurzel-View-Controller

  • eine zweite nav Controller Unterklasse auf Querformat festgelegt, und sein Root-View-Controller, der schwarz ist und als Vermittler fungiert

  • eine dritte Ansicht Controller werden auf den zweiten nav Controller Stack

    geschoben

Wenn der Benutzer fragt „Vorwärts“ von dem ersten View-Controller zu gehen, wir den zweiten Navigationscontroller präsentieren, damit die schwarze Ansicht zu sehen Controller vorübergehend, aber dann wir sofort Push der dritte View-Controller. So bekommen wir eine erzwungene Rotation, zusammen mit einer Art schwarzem Blitz und einer Push-Animation. Wenn der Benutzer im dritten View-Controller auf die Schaltfläche Zurück klickt, wird der Prozess umgekehrt.

Der gesamte Übergangscode befindet sich im Black-View-Controller (ViewControllerIntermediary). Ich habe versucht, es zwicken die befriedigendste Animation kann ich geben:

@implementation ViewControllerIntermediary { 
    BOOL _comingBack; 
} 

- (void) viewDidLoad { 
    [super viewDidLoad]; 
    self.navigationController.delegate = self; 
} 

-(void)navigationController:(UINavigationController *)nc 
     willShowViewController:(UIViewController *)vc 
     animated:(BOOL)anim { 
    if (self == vc) 
     [nc setNavigationBarHidden:YES animated:_comingBack]; 
    else 
     [nc setNavigationBarHidden:NO animated:YES]; 
} 

-(void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    if (!_comingBack) { 
     [self performSegueWithIdentifier:@"pushme" sender:self]; 
     _comingBack = YES; 
    } 
    else 
     [self.navigationController dismissViewControllerAnimated:YES 
      completion:nil]; 
} 
1
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 
{ 
if ([self.window.rootViewController.presentedViewController isKindOfClass: [SecondViewController class]]) 
{ 
    SecondViewController *secondController = (SecondViewController *) self.window.rootViewController.presentedViewController; 

    if (secondController.isPresented) 
     return UIInterfaceOrientationMaskAll; 
    else return UIInterfaceOrientationMaskPortrait; 
} 
else return UIInterfaceOrientationMaskPortrait; 
} 

Und für Swift

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow) -> Int { 

    if self.window?.rootViewController?.presentedViewController? is SecondViewController { 

     let secondController = self.window!.rootViewController.presentedViewController as SecondViewController 

     if secondController.isPresented { 
      return Int(UIInterfaceOrientationMask.All.toRaw()); 
     } else { 
      return Int(UIInterfaceOrientationMask.Portrait.toRaw()); 
     } 
    } else { 
     return Int(UIInterfaceOrientationMask.Portrait.toRaw()); 
    } 

} 

Weitere Details dieses link

Verwandte Themen