2014-03-28 16 views
8

Ich habe eine UIViewController, die modal präsentiert wird (Vollbild) und ich möchte die Autorotation in dieser Ansicht deaktivieren. Ich möchte es nicht auf Landschaften oder Portraits beschränken, ich möchte nur, dass es in der ursprünglichen Ausrichtung bleibt.Autorotation auf iOS 7 für einen einzelnen präsentierten ViewController deaktivieren

auf iOS 6 war es ausreichend, nur die Methode außer Kraft zu setzen:

- (BOOL)shouldAutorotate { 
    return NO; 
} 

Und es tat genau das, was ich wollte. Auf iOS 7 scheint dies jedoch keine Auswirkungen zu haben. Die Methode wird aufgerufen, aber der Rückgabewert scheint vom Betriebssystem ignoriert zu werden - er rotiert automatisch, egal was passiert.

Die Dokumentation erwähnt keine Änderungen an dieser Methode. Wie erreiche ich den gewünschten Effekt auf iOS 7?

Edit: der View-Controller präsentiert wird (nicht gedrückt!) Von einem UINavigationViewController:

[self.navigationController presentViewController:vc animated:YES completion:nil]; 

Lösung:

So seltsam es scheinen mag, aber diese Lösung nicht in veröffentlicht wurde die zahlreichen bestehenden Fragen zu diesem Thema. Auf iOS 7 scheint die Antwort die UINavigationController gibt shouldAutorotate ist, worauf das OS wirkt. Wir müssen die Klasse UINavigationController ableiten, um ihr Verhalten zu ändern.

Wenn Sie mit einem normalen Navigationsstapel umgehen, ist es in der Tat ausreichend, nur [self.topViewController shouldAutorotate] zu verwenden, aber wenn es eine modale Ansicht gibt, befindet es sich in self.presentedViewController, nicht self.topViewController. So ist die vollständige Lösung sieht so aus:

- (BOOL)shouldAutorotate { 
    UIViewController *vc; 
    if (self.presentedViewController) vc = self.presentedViewController; 
    else vc = [self topViewController]; 
    return [vc shouldAutorotate]; 
} 
+0

iOS7 verwendet die View-Controller-Methode 'supportedInterfaceOrientations' den Autorotationsprozess zu steuern, so wie frühere Versionen verwendeten' ShouldAutorotateToInterfaceOrientation: 'Sie auch auf Probleme stoßen, wenn Sie präsentieren den View-Controller in einem 'UITabController'. –

+0

Wird Ihr 'UIViewController' in einem' UINavigationController' dargestellt? –

+0

Mögliches Duplikat von http://stackoverflow.com/questions/12520030/how-to-force-a-uiviewcontroller-to-portait-orientation-in-ios-6 –

Antwort

-1
#import <objc/message.h> 

-(void)viewDidAppear:(BOOL)animated{    

    objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationPortrait); 

} 

How do I programmatically set device orientation in iOS7?

sehen Aber nehmen Sie den Fall, dass Sie diese Methode verwenden, weil es sich um eine private API ist, und Ihre Anwendung kann von Apple abgelehnt werden. So, vielleicht ist es besser, die Orientierung von Projektdetails -> Allgemein -> Deployment Info Registerkarte, wählen Sie nur Querformat links und Querformat rechts. Dies kann ein besserer Ansatz sein, wenn alle Ihre Ansichten nur eine Art von Orientierung benötigen.

+0

Der Aufruf privater APIs kann dazu führen, dass Ihre App abgelehnt wird. –

+0

Sie passen nicht auf. obj/message.h ist tatsächlich in Apples Beispielen enthalten, siehe http://www.opensource.apple.com/source/objc4/objc4-371.1/runtime/message.h – user3344236

+1

Ich weiß 'objc_msgSend' ist in Ordnung. Der Aufruf von 'setOrientation:' ist das Problem, weil die orientation-Eigenschaft von 'UIDevice' als schreibgeschützt deklariert ist. –

5

Also habe ich gerade versucht Sie Code und es funktionierte, was mich zu der Annahme führt, dass Sie Ihre UIViewController in einer UINavigationController präsentieren. Aus welchem ​​Grund auch immer, iOS 7 hat geändert, wie UINavigationController Drehungen handhaben.

Die einfachste Lösung besteht darin, eine Unterklasse von UINavigationController zu erstellen, die die Methode shouldAutorotate überschreibt und den Wert von topViewController zurückgibt.

@interface CustomNavigationController : UINavigationController 

@end 

@implementation CustomNavigationController 

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

@end 

Statt dies zu tun, wo viewController ist Ihr Objekt, das NO für shouldAutorotate zurückzukehren.

UINavigaitonController *navController = [UINavigationController alloc] initWithRootViewController:viewController]; 
[self presentViewController:navController animated:YES completion:nil]; 

Sie würden verwenden, um die CustomNavigationController statt

CustomNavigationController *customNavController = [CustomNavigationController alloc] initWithRootViewController:viewController]; 
[self presentViewController:customNavController animated:YES completion:nil]; 
+0

Danke für den Tipp, aber diese Antwort ist nur teilweise. Dies funktioniert nicht korrekt, wenn 'self.presentedViewController' gesetzt ist, weil' self.presentedViewController'! = 'Self.topViewController' – SaltyNuts

+0

In meinem Fall ist' viewController' nicht in einen anderen 'navController' eingebettet. Es wird ohne navBar im Vollbildmodus angezeigt. Ich habe den Haupt-'navController' in eine Unterklasse umgewandelt, wie Sie es vorgeschlagen haben, aber die Überschreibungen' shouldAutorotate' modifiziert, um nach dem präsentierten View-Controller zu suchen. – SaltyNuts

Verwandte Themen