it-swarm.com.de

iOS6: unterstütztInterfaceOrientations funktioniert nicht (wird aufgerufen, aber die Schnittstelle dreht sich noch)

In meiner App habe ich mehrere Ansichten. Einige Ansichten müssen sowohl das Hoch- als auch das Querformat unterstützen, während andere Ansichten nur das Porträt unterstützen. Daher habe ich in der Projektzusammenfassung alle Orientierungen ausgewählt.

Mit dem folgenden Code konnte der Querformatmodus für einen bestimmten View-Controller vor iOS 6 deaktiviert werden:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

Da sollteAutorotateToInterfaceOrientation in iOS6 nicht mehr empfohlen wird, habe ich das Vorstehende durch Folgendes ersetzt:

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMask.Portrait;
}

Diese Methode wird korrekt aufgerufen, wenn die Ansicht angezeigt wird (ich kann einen Haltepunkt setzen, um dies sicherzustellen), aber die Schnittstelle wird trotzdem in den Querformatmodus gedreht, unabhängig davon, ob die Maske nur für den Hochformatmodus zurückgegeben wird. Was mache ich falsch?

Es scheint derzeit nicht möglich zu sein, eine App zu erstellen, die unterschiedliche Orientierungsanforderungen für jede Ansicht hat. Es scheint nur die in der Projektzusammenfassung angegebenen Ausrichtungen einzuhalten.

50
aneuryzm

Wenn Sie einen UINavigationController als Root-Fenster-Controller verwenden, wird seine shouldAutorotate & supportedInterfaceOrientations aufgerufen.

Idem, wenn Sie einen UITabBarController und so weiter verwenden.

Sie müssen also Ihren Navigations-/Tableisten-Controller subclassieren und seine shouldAutorotate & supportedInterfaceOrientations-Methoden überschreiben.

69
Martin

versuchen Sie, diesen Code in AppDelegate.m zu ändern

//   self.window.rootViewController = self.navigationController;

    [window setRootViewController:navigationController];

das ist die vollständige Antwort

shouldAutorotateToInterfaceOrientation wird in iOS 6 nicht aufgerufen

XD

30
NSStudent

In meinem Fall habe ich UINavigationController und meinen View-Controller. Ich musste UINavigationController subclassieren und, um nur Portrait zu unterstützen, diese Methode hinzufügen:

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}

In der UINavigationController-Unterklasse muss ich also prüfen, welche Ausrichtung vom aktuellen topViewController unterstützt wird.

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

Ich habe festgestellt, dass Sie eine alte Anwendung haben, die noch arbeitet

[window addSubView:viewcontroller.view];  //This is bad in so may ways but I see it all the time...

Sie müssen das aktualisieren, um:

[window setRootViewController:viewcontroller]; //since iOS 4

Sobald Sie dies getan haben, sollte die Orientierung wieder funktionieren.

15
James Jones

Der beste Weg für iOS6 ist insbesondere in "iOS6 By Tutorials" des Ray Wenderlich-Teams vermerkt - http://www.raywenderlich.com/ und ist in den meisten Fällen besser als die UclavingController-Klasse.

Ich verwende iOS6 mit einem Storyboard, das einen UINavigationController als anfänglichen Ansichtscontroller 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 alle Orientierungen zurück, die Sie für jeden UIViewController unterstützen möchten

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}
14
Phil

Wie von anderen angegeben, wenn Sie einen UINavigationController verwenden und verschiedene Ansichten anpassen möchten, möchten Sie den UINavigationController subclassieren und sicherstellen, dass diese beiden Komponenten vorhanden sind:

@implementation CustomNavigationController

// -------------------------------------------------------------------------------
//  supportedInterfaceOrientations:
//  Overridden to return the supportedInterfaceOrientations of the view controller
//  at the top of the navigation stack.
//  By default, UIViewController (and thus, UINavigationController) always returns
//  UIInterfaceOrientationMaskAllButUpsideDown when the app is run on an iPhone.
// -------------------------------------------------------------------------------
- (NSUInteger)supportedInterfaceOrientations
{
    return [self.topViewController supportedInterfaceOrientations]; 
}

// -------------------------------------------------------------------------------
//  shouldAutorotate
//  Overridden to return the shouldAutorotate value of the view controller
//  at the top of the navigation stack.
//  By default, UIViewController (and thus, UINavigationController) always returns
//  YES when the app is run on an iPhone.
// -------------------------------------------------------------------------------
- (BOOL)shouldAutorotate
{
    return [self.topViewController shouldAutorotate];
}

In jeder Ansicht, die nur ein Porträt ist, würden Sie Folgendes enthalten:

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

Und das ist in jeder Hinsicht alles andere als verkehrt:

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}
10
Causaelity

Grundsätzlich, wie oben gesagt, aber ausführlicher:

  1. Erstellen Sie eine neue Datei, die eine Unterklasse von UINavigationController ist
  2. Gehen Sie zu Ihrem Storyboard und klicken Sie dann auf den Navigationscontroller. Legen Sie seine Klasse auf die gerade erstellte fest
  3. Fügen Sie in dieser Klasse (.m-Datei) den folgenden Code hinzu, damit er im Hochformat bleibt:

    (BOOL)shouldAutorotate
    {
      return NO;
    } 
    
    (NSUInteger)supportedInterfaceOrientations
    {
     return UIInterfaceOrientationMaskPortrait;
    }
    

Das hat bei mir funktioniert

2
user1601259

Ich denke, der beste Weg ist, eine Kategorie zu erstellen, anstatt UINavigationController oder UITabbarController

ihr UINavigationController + Rotation.h

#import <UIKit/UIKit.h>

@interface UINavigationController (Rotation)

@end

ihr UINavigationController + Rotation.m

#import "UINavigationController+Rotation.h"

@implementation UINavigationController (Rotation)

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

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

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


@end

Versuchen Sie, alle Ihre Controller diese Kategorie importieren zu lassen, und dies funktioniert wie ein Zauber. Sie können sogar einen Controller drehen, der nicht dreht und einen anderen Controller drückt, der drehen wird.

1
Vassily

Dieser Code hat für mich funktioniert:

-(BOOL)shouldAutorotate {
     return YES;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAll;
}

iPhone/iPad App-Orientierung check meine eigene Antwort

1
tcd

Die Antworten hier wiesen mich in die richtige Richtung, obwohl ich es durch einfaches Ausschneiden und Einfügen nicht schaffen konnte, da ich UINavigationController innerhalb eines UITabBarControllers verwende. Meine Version in AppDelegate.m sieht also ungefähr so ​​aus, was für UITabBarController, UINavigationController oder UINavigationController innerhalb eines UITabBarControllers funktioniert. Wenn Sie andere benutzerdefinierte Containment-Controller verwenden, müssen Sie diese hier hinzufügen (was eine Schande ist).

- (UIViewController*)terminalViewController:(UIViewController*)viewController
{
  if ([viewController isKindOfClass:[UITabBarController class]])
  {
    viewController = [(UITabBarController*)viewController selectedViewController];
    viewController = [self terminalViewController:viewController];
  }
  else if ([viewController isKindOfClass:[UINavigationController class]])
  {
    viewController = [[(UINavigationController*)viewController viewControllers] lastObject];
  }

  return viewController;
}

- (NSUInteger)application:(UIApplication *)application
supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
  NSUInteger orientations = UIInterfaceOrientationMaskPortrait;
  UIViewController* viewController = [self terminalViewController:window.rootViewController];

  if (viewController)
    orientations = [viewController supportedInterfaceOrientations];

  return orientations;
}

Ein weiterer wichtiger Aspekt ist, dass Sie die Zeichenketten der unterstützten Schnittstellen in Ihren UIViewController-Unterklassen überschreiben müssen. Andernfalls werden die in Ihrer Info.plist angegebenen Werte verwendet.

0
Ray Fix

Wenn Sie UINavigationController verwenden, müssen Sie shouldAutorotate und supportedInterfaceOrientations in der Unterklasse von UINavigationController implementieren.

Diese können in zwei Schritten steuern, ob shouldAutorotate JA ergibt und dann supportedInterfaceOrientations wirksam ist. Es ist eine sehr schöne Kombination.

In diesem Beispiel sind meine Ansichten meistens Hochformat mit Ausnahme von CoverFlowView und PreviewView . Die CoverFlowView-Übertragung in PreviewView, PreviewView, möchte der Drehung von CoverFlowCView folgen.

@implementation MyNavigationController

-(BOOL)shouldAutorotate
{

if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromString(@"PreviewView")])

return NO;

else

return YES;

}



-(NSUInteger)supportedInterfaceOrientations

{

if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromString(@"CoverFlowView")])

return UIInterfaceOrientationMaskAllButUpsideDown;

else

return UIInterfaceOrientationMaskPortrait;

}

...

@end
0
Y.Muranaka

meine Lösung: Unterklasse UINavigationController und als window.rootViewController gesetzt

der Top-Viewcontroller der Hierarchie übernimmt die Kontrolle über die Ausrichtung, einige Codebeispiele: Unterklasse UINavigationController

0
Carina

Versuchen Sie, die Methode shouldAutorotate hinzuzufügen

0
Kubba

Ich habe die gleiche Situation wie Sie. Ich weiß, dass Sie eine Antwort bereits akzeptiert haben, aber ich dachte, ich würde sowieso noch eine hinzufügen. So verstehe ich, dass die neue Version des Rotationssystems funktioniert. Der Root-View-Controller ist der einzige View-Controller, der jemals aufgerufen wurde. Ich denke, die Begründung ist, dass es bei untergeordneten Ansichtscontrollern nicht sinnvoll ist, ihre Ansichten zu drehen, da sie ohnehin nur im Rahmen des Root-Viewcontrollers bleiben. 

Was passiert also? Zuerst heißt shouldAutorotateauf dem Root-View-Controller. Wenn NO zurückgegeben wird, stoppt alles. Wenn YES zurückgegeben wird, wird die supportedInterfaceOrientations-Methode aufgerufen. Wenn in dieser Methode die Schnittstellenausrichtung bestätigt wird und die global unterstützten Ausrichtungen entweder aus der Info.plist oder aus dem Anwendungsdelegierten, wird die Ansicht gedreht. Vor der Rotation wird die shouldAutomaticallyForwardRotationMethods-Methode abgefragt. Wenn YES (Standardeinstellung), erhalten alle Kinder die Methoden will und didRotateTo... sowie das übergeordnete Element (und sie leiten es an ihre Kinder weiter).

Meine Lösung (bis es eine eloquentere gibt) besteht darin, den letzten untergeordneten Ansichtscontroller während der supportedInterfaceOrientations-Methode abzufragen und seinen Wert zurückzugeben. Dadurch kann ich einige Bereiche drehen, während andere nur im Porträt bleiben. Ich weiß, dass es fragil ist, aber ich sehe keinen anderen Weg, bei dem es nicht darum geht, Dinge mit Ereignisanrufen, Rückrufen usw. zu komplizieren. 

0
borrrden

Damit Ihre App nur im Modus funktioniert, sollten Sie UIInterfaceOrientationMaskLandscape zurückgeben. Wenn Sie nur den Hochformatmodus beibehalten möchten, machen Sie die Dinge richtig.

Fügen Sie einfach den Schlüssel UISupportedInterfaceOrientations in die Info.plist ein und weisen Sie den Werten für die Schnittstellenorientierung zu, die Ihre App beibehalten möchte.

Sie sollten auch false von shouldAutoRotate zurückgeben, wenn Sie die automatische Drehung vollständig vermeiden möchten. Aber ich würde vorschlagen, dass Sie von hier aus wahr zurückgeben und die korrekte Ausrichtung in der supportedInterfaceOrientations-Methode angeben.

0
Varun Bhatia