Antworten:
Wenn Sie möchten, dass alle unsere Navigations-Controller den Draufsicht-Controller respektieren, können Sie eine Kategorie verwenden, damit Sie nicht eine Reihe von Klassennamen ändern müssen.
@implementation UINavigationController (Rotation_IOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
@end
Wie einige Kommentare zeigen, ist dies eine schnelle Lösung für das Problem. Eine bessere Lösung ist der UINavigationController der Unterklasse, in dem diese Methoden abgelegt werden. Eine Unterklasse hilft auch bei der Unterstützung von 6 und 7.
Der beste Weg für iOS6 wird speziell in "iOS6 By Tutorials" vom Ray Wenderlich-Team - http://www.raywenderlich.com/ - angegeben und ist in den UINavigationController
meisten Fällen besser als Unterklassen .
Ich verwende iOS6 mit einem Storyboard, das einen UINavigationController
Satz als anfänglichen Ansichts-Controller enthält.
//AppDelegate.m - Diese Methode ist vor iOS6 leider nicht verfügbar
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;
if(self.window.rootViewController){
UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
//MyViewController.m - Gibt die Orientierungen zurück, die Sie für jede unterstützen möchten UIViewController
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
Diese Antwort bezieht sich auf die Fragen, die in den Kommentaren des OP-Beitrags gestellt wurden:
Um zu erzwingen, dass eine Ansicht in einer bestimmten Ausrichtung angezeigt wird, fügen Sie Folgendes in viewWillAppear ein:
UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
UIViewController *c = [[UIViewController alloc]init];
[self presentModalViewController:c animated:NO];
[self dismissModalViewControllerAnimated:NO];
}
Es ist ein bisschen wie ein Hack, aber dies erzwingt die UIViewController
Darstellung im Hochformat, selbst wenn der vorherige Controller Querformat war
UPDATE für iOS7
Die oben genannten Methoden sind jetzt veraltet. Verwenden Sie daher für iOS 7 Folgendes:
UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
UIViewController *c = [[UIViewController alloc]init];
[c.view setBackgroundColor:[UIColor redColor]];
[self.navigationController presentViewController:c animated:NO completion:^{
[self.navigationController dismissViewControllerAnimated:YES completion:^{
}];
}];
}
Interessanterweise muss zum Zeitpunkt des Schreibens entweder die Gegenwart oder die Entlassung animiert sein. Wenn beides nicht der Fall ist, erhalten Sie einen weißen Bildschirm. Keine Ahnung, warum das funktioniert, aber es funktioniert! Der visuelle Effekt ist je nach Animation unterschiedlich.
Daher stieß ich auf das gleiche Problem, wenn nur modale Hochformatansichten angezeigt wurden. Normalerweise würde ich eine erstellen UINavigationController
, die viewController
als festlegen rootViewController
und dann die UINavigationController
als modale Ansicht anzeigen. Bei iOS 6 viewController
wird der Navigationscontroller nun nach den unterstützten Schnittstellenausrichtungen gefragt (die jetzt standardmäßig nur für das iPad und für das iPhone alles andere als verkehrt herum sind).
Lösung : Ich musste UINavigationController
die Autorotationsmethoden unterordnen und überschreiben. Irgendwie lahm.
- (BOOL)shouldAutorotate {
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
// pre-iOS 6 support
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}
IOS 5
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
IOS 6
-(BOOL)shouldAutorotate{
return YES;
}
-(NSInteger)supportedInterfaceOrientations{
// UIInterfaceOrientationMaskLandscape;
// 24
//
// UIInterfaceOrientationMaskLandscapeLeft;
// 16
//
// UIInterfaceOrientationMaskLandscapeRight;
// 8
//
// UIInterfaceOrientationMaskPortrait;
// 2
// return UIInterfaceOrientationMaskPortrait;
// or
return 2;
}
Ich bin mit der Antwort von @aprato nicht einverstanden, da die UIViewController-Rotationsmethoden in Kategorien selbst deklariert sind, was zu undefiniertem Verhalten führt, wenn Sie dann in einer anderen Kategorie überschreiben. Es ist sicherer, sie in einer UINavigationController- (oder UITabBarController-) Unterklasse zu überschreiben
Dies gilt auch nicht für das Szenario, in dem Sie aus einer Querformatansicht nur VC in ein Hochformat verschieben / präsentieren / einfügen oder umgekehrt. Um dieses schwierige Problem zu lösen (das von Apple nie angesprochen wurde), sollten Sie:
In iOS <= 4 und iOS> = 6:
UIViewController *vc = [[UIViewController alloc]init];
[self presentModalViewController:vc animated:NO];
[self dismissModalViewControllerAnimated:NO];
[vc release];
In iOS 5:
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview];
[window addSubview:view];
Diese werden UIKit WIRKLICH dazu zwingen, alle Ihre SollteAutorotate, unterstütztenInterfaceOrientations usw. neu zu bewerten.
Ich habe einen sehr guten Ansatz beim Mischen von https://stackoverflow.com/a/13982508/2516436 und https://stackoverflow.com/a/17578272/2516436
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;
if(self.window.rootViewController){
UIViewController *presentedViewController = [self topViewControllerWithRootViewController:self.window.rootViewController];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
if ([rootViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController* tabBarController = (UITabBarController*)rootViewController;
return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
} else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController* navigationController = (UINavigationController*)rootViewController;
return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
} else if (rootViewController.presentedViewController) {
UIViewController* presentedViewController = rootViewController.presentedViewController;
return [self topViewControllerWithRootViewController:presentedViewController];
} else {
return rootViewController;
}
}
und geben Sie die Orientierungen zurück, die Sie für jeden UIViewController unterstützen möchten
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
Ich habe eine relativ komplexe universelle App mit UISplitViewController und UISegmentedController und habe einige Ansichten, die in Querformat mit dargestellt werden müssen presentViewController
. Mit den oben vorgeschlagenen Methoden konnte ich das iPhone ios 5 & 6 akzeptabel zum Laufen bringen, aber aus irgendeinem Grund weigerte sich das iPad einfach, es als Landschaft darzustellen. Schließlich fand ich eine einfache Lösung (implementiert nach stundenlangem Lesen und Ausprobieren), die sowohl für Geräte als auch für iOS 5 und 6 funktioniert.
Schritt 1) Geben Sie auf dem Controller die erforderliche Ausrichtung an (mehr oder weniger wie oben angegeben).
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
NSInteger mask = UIInterfaceOrientationMaskLandscape;
return mask;
}
Schritt 2) Erstellen Sie eine einfache UINavigationController-Unterklasse und implementieren Sie die folgenden Methoden
-(BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
Schritt 3) Präsentieren Sie Ihren viewController
vc = [[MyViewController alloc]init];
MyLandscapeNavigationController *myNavigationController = [[MyLandscapeNavigationController alloc] initWithRootViewController:vc];
[self myNavigationController animated:YES completion:nil];
Hoffe das ist hilfreich für jemanden.
Hier nicht langweilig zu sein, aber würden Sie so freundlich sein, Ihre Unterklasse zu teilen? Danke dir.
edit: nun, ich habe es endlich geschafft, die Unterklasse war kinderleicht zu machen. Ich musste nur die navigationController
in der AppDelegate
als UINavigationControllerSubclass
anstelle der Standardeinstellung deklarieren UINavigationController
und dann Ihre Unterklasse ändern mit:
- (BOOL)shouldAutorotate {
return _shouldRotate;
}
So kann ich jede Ansicht einstellen, die ich drehen möchte oder nicht, indem ich anrufe viewDidLoad
_navController = (UINavigationController *)self.navigationController;
[_navController setShouldRotate : YES / NO]
Hoffe, diese Optimierung wird auch anderen helfen, danke für deinen Tipp!
Tipp: Nutzen Sie
- (NSUInteger)supportedInterfaceOrientations
Sie haben also nicht die gewünschte Hochformatansicht im Querformat oder umgekehrt.
Ich habe es nicht selbst getestet, aber die Dokumentation besagt, dass Sie diese Methoden jetzt überschreiben können: supportedInterfaceOrientations
und preferredInterfaceOrientationForPresentation
.
Sie können wahrscheinlich das erreichen, was Sie wollen, indem Sie nur die gewünschte Ausrichtung für diese Methoden festlegen.
Die Antworten unter Verwendung von Unterklassen oder Kategorien, um VCs in den Klassen UINavigationController und UITabBarController zuzulassen, funktionieren gut. Das Starten eines Nur-Hochformat-Modals von einem Querformat-Controller in der Registerkartenleiste ist fehlgeschlagen. Wenn Sie dies tun müssen, verwenden Sie den Trick, eine nicht animierte modale Ansicht anzuzeigen und auszublenden , aber tun Sie dies in der viewDidAppear-Methode . In viewDidLoad oder viewWillAppear hat es bei mir nicht funktioniert.
Abgesehen davon funktionieren die oben genannten Lösungen einwandfrei.
Für Monotouch können Sie dies folgendermaßen tun:
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
{
return UIInterfaceOrientationMask.LandscapeRight;
}
public override UIInterfaceOrientation PreferredInterfaceOrientationForPresentation()
{
return UIInterfaceOrientation.LandscapeRight;
}
Ich sehe die vielen Antworten, bekomme aber nicht die bestimmte Idee und Antwort über die Ausrichtung, sehe aber den Link gut, verstehe die Ausrichtung und entferne die kraftvolle Drehung für ios6.
http://www.disalvotech.com/blog/app-development/iphone/ios-6-rotation-solution/
Ich denke es ist Hilfe voll.
Gehen Sie einfach zu project.plist, fügen Sie die Ausrichtung der unterstützten Benutzeroberfläche hinzu und fügen Sie dann nur Portrait (untere Home-Schaltfläche) und Portrait (obere Home-Schaltfläche) hinzu.
Sie können diese Ausrichtung gemäß Ihren Projektanforderungen hinzufügen oder entfernen.
Vielen Dank
1) Überprüfen Sie Ihre Projekteinstellungen und info.plist und stellen Sie sicher, dass nur die gewünschten Ausrichtungen ausgewählt sind.
2) Fügen Sie Ihrem obersten Ansichts-Controller (Navigations-Controller / Tabbar-Controller) die folgenden Methoden hinzu.
- (NSUInteger) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
3) Fügen Sie Ihrem App-Delegaten die folgenden Methoden hinzu
- (NSUInteger) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait;
}
Fügen Sie dies in die .m-Datei von jedem ein, den ViewController
Sie nicht drehen möchten:
- (NSUInteger)supportedInterfaceOrientations
{
//return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft;
return UIInterfaceOrientationMaskPortrait;
}
Sehen Sie hier für weitere Informationen.