iOS 6: Wie beschränke ich einige Ansichten auf Hochformat und erlaube anderen, sich zu drehen?

99

Ich habe eine iPhone-App, die eine UINavigationControllerDrilldown-Oberfläche verwendet: Zuerst eine Ansicht, dann eine andere, bis zu vier Ebenen tief. Ich möchte, dass die ersten drei Ansichten auf die Ausrichtung im Hochformat beschränkt sind und nur die letzte Ansicht im Querformat gedreht werden darf. Bei der Rückkehr von der vierten zur dritten und vierten Ansicht im Querformat möchte ich, dass sich alles wieder im Hochformat dreht.

In iOS 5 habe ich einfach shouldAutorotateToInterfaceOrientation:in jedem meiner Ansichts-Controller definiert, dass für die zulässigen Ausrichtungen JA zurückgegeben werden soll. Alles funktionierte wie oben beschrieben, einschließlich der Rückkehr zum Hochformat, auch wenn das Gerät bei der Rückkehr von View Controller Nr. 4 zu Nr. 3 im Querformat gehalten wurde.

In iOS 6 drehen sich alle View-Controller in den Querformat und brechen diejenigen, die nicht dazu gedacht waren. In den Versionshinweisen zu iOS 6 heißt es

Es wird mehr Verantwortung auf die App und den App-Delegierten übertragen. Jetzt UINavigationControllerkonsultieren iOS-Container (z. B. ) ihre Kinder nicht mehr, um festzustellen, ob sie eine Autorotation durchführen sollen. [...] Das System fragt den obersten Vollbild-View-Controller (normalerweise den Root-View-Controller) nach seinen unterstützten Schnittstellenausrichtungen, wenn sich das Gerät dreht oder wenn einem View-Controller der modale Vollbild-Präsentationsstil präsentiert wird. Darüber hinaus werden die unterstützten Ausrichtungen nur abgerufen, wenn dieser Ansichtscontroller von seiner shouldAutorotateMethode JA zurückgibt . [...] Das System ermittelt, ob eine Ausrichtung unterstützt wird, indem es den von der App- supportedInterfaceOrientationsForWindow:Methode zurückgegebenen Wert mit dem von der supportedInterfaceOrientationsMethode des obersten Vollbild-Controllers zurückgegebenen Wert schneidet .

Also habe ich eine Unterklasse erstellt UINavigationController, meine MainNavigationControllerboolesche Eigenschaft angegeben landscapeOKund diese verwendet, um die zulässigen Ausrichtungen in zurückzugeben supportedInterfaceOrientations. Dann habe ich in jeder viewWillAppear:Methode meiner View Controller eine Zeile wie diese

    [(MainNavigationController*)[self navigationController] setLandscapeOK:YES];

um mir MainNavigationControllerdas gewünschte Verhalten zu sagen .

Hier kommt die Frage: Wenn ich jetzt im Hochformat zu meiner vierten Ansicht navigiere und das Telefon umdrehe, dreht es sich in Querformat. Jetzt drücke ich die Zurück-Taste, um zu meiner dritten Ansicht zurückzukehren, die nur im Hochformat funktionieren soll. Aber es dreht sich nicht zurück. Wie mache ich das?

Ich habe es versucht

    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait]

in der viewWillAppearMethode meines dritten View Controllers, aber es macht nichts. Ist dies die falsche Methode zum Aufrufen oder vielleicht der falsche Ort zum Aufrufen oder sollte ich das Ganze auf eine völlig andere Art und Weise implementieren?

Harald Bögeholz
quelle

Antworten:

95

Ich hatte das gleiche Problem und fand eine Lösung, die für mich funktioniert. Damit es funktioniert, reicht es nicht aus, es - (NSUInteger)supportedInterfaceOrientationsin Ihrem UINavigationController zu implementieren . Sie müssen diese Methode auch in Ihrem Controller Nr. 3 implementieren, der nach dem Poppen von Controller Nr. 4 als erster nur im Hochformat ausgeführt wird. Ich habe also den folgenden Code in meinem UINavigationController:

- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    if (self.isLandscapeOK) {
        // for iPhone, you could also return UIInterfaceOrientationMaskAllButUpsideDown
        return UIInterfaceOrientationMaskAll;
    }
    return UIInterfaceOrientationMaskPortrait;
}

Fügen Sie in View Controller Nr. 3 Folgendes hinzu:

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

Sie müssen Ihren View Controllern Nr. 1, Nr. 2 und Nr. 4 nichts hinzufügen. Das funktioniert bei mir, ich hoffe es wird dir helfen.

Flo
quelle
8
Sie haben etwas gelöst, das die Leute monatelang zu lösen versuchten! Sie verdienen viel Anerkennung dafür! Ich habe unterstützteInterfaceOrientations zu einer Kategorie in UIViewController hinzugefügt und es funktioniert perfekt als Standard für diese Nur-Hochformat-Controller.
Dwery
3
Unter 100 verschiedenen Antworten auf SO ist dies diejenige, die wirklich funktioniert. Danke :-)
Christer Nordvik
16
Ich habe dies eingerichtet und bekomme immer noch eine falsche Ausrichtung, wenn ich vom Hochformat zu einem Ansichts-Controller zurückkehre, der nur auf Querformat beschränkt ist. Es dreht sich nicht automatisch zur Landschaft - sieht es noch jemand?
Oded Ben Dov
1
Was ist, wenn der gewünschte Landschaftsansichts-Controller aus einem Segue angezeigt wird und kein Navigations-Controller vorhanden ist?
jesses.co.tt
1
Bearbeiten Sie den letzten NSUInteger als Rückgabetyp.
Absessive
68

Fügen Sie einen CustomNavigationController hinzu

Überschreiben Sie diese Methoden darin:

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

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

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

Fügen Sie nun alle Ausrichtungen in die Liste ein

Geben Sie hier die Bildbeschreibung ein

Fügen Sie im View Controller nur die erforderlichen hinzu:

-(BOOL)shouldAutorotate
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

Diese Methoden überschreiben die Navigationssteuerungsmethoden

Zaraki
quelle
5
Sie haben es wirklich mit dieser Antwort geschafft! Ich danke dir sehr. Du hast wirklich sehr geholfen. Das ist seit einiger Zeit ein großes Problem für mich. Gut gemacht.
K2Digital
Danke! Ich habe so viel Zeit und Energie gebraucht, um das herauszufinden!
bkbeachlabs
Du bist ein Lebensretter ... Das funktioniert auch in meiner App. Eigentlich möchte ich in meiner App, dass sich alle ViewControllerim Porträtmodus befinden und meine ViewControllerim Landschafts- und Porträtmodus. Ich gebe auch Unterstützung in iOS 5.0 und iOS 6.0. Deshalb bin ich verwirrt, um herumzuarbeiten, aber das ist eine großartige Lösung. Ich füge CustomNavigationController zu meinem Root View Controller hinzu und gebe Unterstützung entsprechend meinen Anforderungen. Noch einmal vielen Dank.
Bhavin_m
Fantastisch. Genau das, was ich brauchte. Danke dir.
Mszaro
Was ist, wenn der gewünschte Landschaftsansichts-Controller aus einem Segue angezeigt wird und kein Navigations-Controller vorhanden ist?
jesses.co.tt
9

Nachdem ich jede Antwort in unzähligen ähnlichen Fragen zu SO durchgesehen hatte, funktionierte keine der Antworten für mich, aber sie gaben mir einige Ideen. So habe ich das Problem gelöst:

Stellen Sie zunächst sicher, dass Ihre unterstützten Schnittstellenausrichtungen im Ziel Ihres Projekts alle Ausrichtungen enthalten, die Sie für Ihre rotierende Ansicht benötigen.

Geben Sie hier die Bildbeschreibung ein

Erstellen Sie als Nächstes eine Kategorie von UINavigationController(da Apple sagt, dass keine Unterklasse erstellt werden soll):

@implementation UINavigationController (iOS6AutorotationFix)

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

@end

Importieren Sie diese Kategorie und den Ansichts-Controller, den Sie drehen möchten (was ich nennen werde RotatingViewController), in Ihren Ansichts-Controller der höchsten Ebene, der Ihren Navigations-Controller enthalten soll. Implementieren Sie in diesem Ansichts-Controller shouldAutorotateFolgendes. Beachten Sie, dass dies nicht derselbe Ansichtscontroller sein sollte, den Sie drehen möchten.

-(BOOL)shouldAutorotate {

    BOOL shouldRotate = NO;

    if ([navigationController.topViewController isMemberOfClass:[RotatingViewController class]] ) {
        shouldRotate = [navigationController.topViewController shouldAutorotate];
    }

    return shouldRotate;
}

Schließlich RotatingViewControllerimplementieren Sie in Ihrem shouldAutorotateund supportedInterfaceOrientationswie folgt:

-(BOOL)shouldAutorotate {
    // Preparations to rotate view go here
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAllButUpsideDown; // or however you want to rotate
}

Der Grund dafür ist, dass iOS 6 dem Root-View-Controller anstelle des Top-View-Controllers die Steuerung der Rotation ermöglicht. Wenn Sie möchten, dass sich die Rotation einer einzelnen Ansicht anders verhält als andere Ansichten im Stapel, müssen Sie einen bestimmten Fall dafür in den Root-Ansichts-Controller schreiben.

Brian
quelle
2
Dies ist eine ausgezeichnete Antwort, die mehr Liebe verdient. Hier ist die Information, die ich nirgendwo anders finden konnte und die von entscheidender Bedeutung ist: Wenn Sie möchten, dass sich die Rotation einer einzelnen Ansicht anders verhält als andere Ansichten im Stapel, müssen Sie einen bestimmten Fall dafür in das Stammverzeichnis schreiben View Controller
Shmim
Ich nehme an, dass dies funktioniert, wenn Sie einen Navigationscontroller als erstes Mitglied des Storyboards Ihrer App als anfänglichen Controller haben. Aber was ist mit dem Fall, wenn der anfängliche Controller einfach ein ViewController ist?
Ente
4

Ich habe nicht genug Ruf, um die Antwort von @ Brian zu kommentieren, daher werde ich meine Notiz hier hinzufügen.

Brian erwähnte, dass iOS6 dem rootViewController die Rotationssteuerung gibt - dies könnte nicht nur ein UINavigationController sein, wie erwähnt, sondern auch ein UITabBarController, der für mich war. Meine Struktur sieht so aus:

  • UITabBarController
    • UINavigationController
      • UIViewController ...
    • UINavigationController
      • UIViewController ...

Also habe ich die Methoden zuerst in einem benutzerdefinierten UITabBarController, dann in einem benutzerdefinierten UINavigationController und zuletzt in dem spezifischen UIViewController hinzugefügt.

Beispiel aus dem UITabBarController und UINavigationController:

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

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

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return [self.viewControllers.lastObject shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return [self.viewControllers.lastObject preferredInterfaceOrientationForPresentation];
}
micmdk
quelle
Ich habe tatsächlich einen UITabBarController als Instanzvariable in meinem Root-View-Controller verwendet, da Sie UITabBarController in iOS-Versionen vor 6.0 nicht in Unterklassen unterteilen sollten und ich Unterstützung für iOS 5.0 benötigen musste.
Brian
@micmdk Ich habe das gleiche Problem. Bitte geben Sie an, wie das Problem behoben werden soll. Ich habe Ihren Code kopiert und in den benutzerdefinierten Navigations-Controller und den benutzerdefinierten UabbarController eingefügt und einen anderen Ansichts-Controller als Brian's Guided festgelegt. aber immer noch nicht fixe Ansicht Controller im Hochformat.
Ram S
@ Brian Ich habe das gleiche Problem. Bitte geben Sie an, wie das Problem behoben werden soll. Ich habe Ihren Code kopiert und in den benutzerdefinierten Navigationscontroller und den benutzerdefinierten UabbarController eingefügt und einen anderen Ansichtscontroller als Micmdk's Guided festgelegt. In ios8 wird jedoch immer noch kein Fixed View Controller im Hochformat angezeigt.
Ram S
3

Ich möchte eine teilweise Antwort auf meine eigene Frage geben. Ich fand die folgende Codezeile, die in der viewWillAppearMethode meines dritten verwendet wurde UIViewController, um zu funktionieren:

[[UIDevice currentDevice] 
      performSelector:NSSelectorFromString(@"setOrientation:") 
           withObject:(id)UIInterfaceOrientationPortrait];

Aber ich mag diese Lösung nicht wirklich. Es wird ein Trick verwendet, um einer schreibgeschützten Eigenschaft zuzuweisen, die laut Apple-Dokumentation die physische Ausrichtung des Geräts darstellt. Es ist, als würde man dem iPhone sagen, dass es in der Hand des Benutzers zur richtigen Ausrichtung springen soll.

Ich bin sehr versucht, dies in meiner App zu belassen, da es einfach funktioniert. Aber es fühlt sich nicht richtig an, deshalb möchte ich die Frage für eine saubere Lösung offen lassen.

Harald Bögeholz
quelle
4
Ihre App wird höchstwahrscheinlich abgelehnt, wenn Sie sie dort lassen. Ich suche auch nach einer Lösung dafür, aber es scheint nicht möglich zu sein. Alles, was ich finden konnte, ist die Antwort auf diese Frage: stackoverflow.com/questions/7196300/… es funktioniert irgendwie, aber aus irgendeinem Grund bricht es die Tastenberührung in einem meiner Viewcontroller
Lope
Ich habe mein Risiko eingegangen und mich bei Apple gemeldet. Ich warte immer noch auf eine Überprüfung ... Ich halte Sie auf dem Laufenden.
Harald Bögeholz
Apple hat gerade meine App mit diesem Hack genehmigt, yey! Ich hoffe, dass es in einem zukünftigen iOS-Update nicht nach hinten losgeht. In der Zwischenzeit bin ich noch offen für Vorschläge für eine saubere Lösung!
Harald Bögeholz
1
@ HaraldBögeholz Grt suggetion. aber wenn ich in neuem xCode mit ARC arbeite, kann ich die ans nicht verwenden. Ich erhalte die Meldung "Die Umwandlung von NSInteger (auch bekannt als int) in id ist mit ARC nicht zulässig. PerformSelector kann ein Leck verursachen, da der Selektor unbekannt ist." Wie kann ich das beheben? Ich bin Ihnen sehr dankbar, wenn wir eine Lösung haben. Wenn ich ARC für eine bestimmte Ansicht ausschalte, stürzt die App aufgrund einiger Leckdaten ab. Bitte schlagen Sie mich vor
Hitarth
4
Die Verwendung einer privaten API ist NIE die Lösung.
Javier Soto
2

Dies verwende ich zur Orientierungsunterstützung in iOS 6.0

-(BOOL)shouldAutorotate{
    return YES;
}  

 - (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskAll;
}


- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{  
  return UIInterfaceOrientationPortrait;
}
ASHISHT
quelle
1

Dies ist ein hoch angesehener Thread. Ich dachte, ich würde hinzufügen, was meiner Meinung nach die einfachste Antwort ist. Dies funktioniert für ios8 und höher

-(BOOL)shouldAutorotate
{
    return YES;
}

und

-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}

Das ist es. Genießen!

Oh, und meine ViewController sind in einen Navigationscontroller eingebettet, den ich in keiner Weise unterklassifizieren oder konfigurieren musste.

Reeder32
quelle
0

Das funktioniert vielleicht nicht für alle, aber für mich funktioniert es großartig. Anstatt zu implementieren ...

[(MainNavigationController*)[self navigationController] setLandscapeOK:YES];

In viewWillAppear in allen meinen Controllern habe ich beschlossen, diesen Prozess innerhalb meiner UINavigationController-Unterklasse zu zentralisieren, indem ich die UINavigationControllerDelegate- Methode überschreibenavigationController:willShowViewController:animated:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {

    self.previousVCLandscapeOK = self.isLandscapeOK; // Store the current VC's orientation preference before pushing on the new VC so we can set this again from within the custom "back" method
    self.isLandscapeOK = NO; // Set NO as default for all VC's
    if ([viewController isKindOfClass:[YourViewController class]]) {
        self.isLandscapeOK = YES;
    }
}

Ich habe festgestellt, dass diese Delegatenmethode nicht aufgerufen wird, wenn eine VC vom Navigationsstapel entfernt wird. Dies war für mich kein Problem, da ich die Back-Funktionalität in meiner UINavigationController-Unterklasse verwalte, damit ich die richtigen Schaltflächen und Aktionen für die Navigationsleiste für bestimmte VCs wie diese festlegen kann ...

if ([viewController isKindOfClass:[ShareViewController class]]) {

    UIButton* backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 57, 30)];
    [backButton setImage:[UIImage imageNamed:@"back-arrow"] forState:UIControlStateNormal];
    [backButton addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem* backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    viewController.navigationItem.leftBarButtonItem = backButtonItem;

    UIImageView* shareTitle = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"share-title"]];
    [shareTitle setContentMode:UIViewContentModeScaleAspectFit];
    [shareTitle setFrame:CGRectMake(0, 0, shareTitle.frame.size.width - 10, shareTitle.frame.size.height - 10)];
    viewController.navigationItem.titleView = shareTitle;

} else if(...) {
    ...
}

So backsieht meine Methode aus, um die VC vom Stapel zu entfernen und die entsprechende Rotationseinstellung festzulegen ...

- (void)back {
    self.isLandscapeOK = self.previousVCLandscapeOK;
    self.previousVCLandscapeOK = NO;
    [self popViewControllerAnimated:YES];
}

Wie Sie sehen, ist im Grunde alles, was passiert, dass ich mir zuerst zwei Eigenschaften einstelle ...

@property (nonatomic) BOOL isLandscapeOK;
@property (nonatomic) BOOL previousVCLandscapeOK;

in navigationController:willShowViewController:animated:dem bestimmt wird, welche unterstützten Orientierungen innerhalb der VC liegen, die präsentiert werden soll. Beim Poppen einer VC wird meine benutzerdefinierte "back" -Methode aufgerufen, und ich setze dann isLandscapeOK auf das, was über den vorherigen Wert von VCLandscapeOK gespeichert wurde.

Wie gesagt, dies funktioniert möglicherweise nicht für alle, aber es funktioniert hervorragend für mich und ich muss mir keine Gedanken über das Hinzufügen von Code zu jedem meiner View-Controller machen. Ich konnte alles zentral in der UINavigationController-Unterklasse halten.

Hoffe das hilft jemandem wie mir. Danke, Jeremy.

Jeremy Fox
quelle
0

Gehen Sie zu Ihrer Info.plist-Datei und nehmen Sie die Änderung vorGeben Sie hier die Bildbeschreibung ein

Nekelle Latoya Celestine
quelle
0

Sie möchten das Portrait der iOS 6-App nur dann erzwingen, wenn Sie eine der folgenden Methoden zu einer UIViewController-Unterklasse hinzufügen können

- (BOOL)shouldAutorotate {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        return YES;
    } else {
        return NO;
    }
}


- (NSUInteger)supportedInterfaceOrientations {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        return UIInterfaceOrientationMaskAll;
    } else {
        return UIInterfaceOrientationMaskPortrait;
    }
}
Vaibhav Saran
quelle
2
Das Problem ist, dass sollteAutorotate nicht aufgerufen wird, es sei denn, diese Ansicht ist die Stammansicht (was in dieser Frage nicht enthalten ist).
Brian
Aus irgendeinem Grund gibt return return NSUIntegereine Warnung aus, obwohl es sich um den richtigen var-Typ handelt. Wenn Sie OCD haben, verwenden Sie UIInterfaceOrientationMaskstattdessen.
Chris J
Diese Lösung funktionierte auch perfekt für einen Modal View Controller (eine Kameraansicht), den ich habe, ohne dass UINavigationController in Unterklassen unterteilt werden muss. Ich vermute, Modalitäten werden unabhängig behandelt. Nicht relevant für die ursprüngliche Frage, aber nützliche Informationen für das Design.
Chris J
0

Ich wollte, dass alle meine VCs bis auf einen auf Hochformat ausgerichtet sind. Das hat bei mir funktioniert.

  1. Unterstützung für alle Ausrichtungen in der Plist-Datei hinzufügen.
  2. Ermitteln Sie im Root-View-Controller die Art des View-Controllers, der sich oben im Fenster befindet, und legen Sie die Ausrichtung der App in der unterstützten Methode InterfaceOrientations entsprechend fest . Zum Beispiel musste meine App nur gedreht werden, wenn sich die Webansicht oben auf dem Stapel befand. Folgendes habe ich in meinem rootVC hinzugefügt:

    -(NSUInteger)supportedInterfaceOrientations
    {
        UIViewController *topMostViewController = [[Utils getAppDelegate] appNavigationController].topViewController;
        if ([topMostViewController isKindOfClass:[SVWebViewController class]]) {
            return UIInterfaceOrientationMaskAllButUpsideDown;
        }
        return UIInterfaceOrientationMaskPortrait;
    }
Trunal Bhanse
quelle
Trunal, Dies ist ein paar Monate alt, aber können Sie etwas detaillierter angeben, wie Sie die Art des Ansichts-Controllers erkennen, der sich oben befindet? Insbesondere bin ich mir nicht sicher, was Sie hier vorhaben [[Utils getAppDelegate] appNavigationController]. Ich vermute, Utils ist eine Klasse, die Sie haben, aber ich bin ratlos, was Sie darin tun. Jede Hilfe wäre toll!
Ben
0

Ich habe nicht genug Ruf, um die @ Ram S-Frage unter @micmdk-Antwort zu beantworten, daher werde ich meine Notiz hier hinzufügen.

Wenn Sie UITabbarController verwenden , versuchen Sie, self.viewControllers.lastObject im Code von @ micmdk wie folgt in self.selectedViewController zu ändern :

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

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

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return [self.selectedViewController shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return [self.selectedViewController preferredInterfaceOrientationForPresentation];
}
phantom_2
quelle
0

Sie können in allen View Controller-Klassen, die in einer anderen Ausrichtung als der in PLIST Ihrer App definierten angezeigt werden sollen, shouldAutorotate () und supportInterfaceOrientations var implementieren und überschreiben.

In einer nicht trivialen Benutzeroberfläche kann es jedoch zu Problemen beim Hinzufügen in Dutzenden von Klassen kommen, und Sie möchten nicht alle Unterklassen mehrerer allgemeiner Klassen festlegen, die dies unterstützen (MyBaseTableViewController, MyBaseNavigationController und MyBaseTabBarController).

Da Sie diese Methode / var in UIViewController nicht direkt überschreiben können, können Sie dies in seinen Unterklassen tun, die normalerweise Ihre Basisklassen sind, wie UITableViewController, UINavigationController und UITabBarController.

Sie können also einige Erweiterungen implementieren und MyPreciousViewController dennoch so einrichten, dass es in einer anderen Ausrichtung als alle anderen wie dieses Swift 4-Codefragment angezeigt wird:

extension UITableViewController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {

    if let last = self.navigationController?.childViewControllers.last,
        last != self {
            return last.supportedInterfaceOrientations
    } else {
        return [.portrait]
    }
    }
}

extension MyPreciousViewController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {

    return [.portrait,.landscape]
    }
}


extension UINavigationController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {

        return [.portrait]
    }
}


extension UITabBarController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {

        return [.portrait]
    }
}
Vedrano
quelle
0

Ich habe das gleiche Problem gelöst.

Wenn Sie UINavigationControllerdie Ansichts-Controller mit p drücken, müssen Sie die folgenden Methoden festlegen.

extension UINavigationController{

    override open var shouldAutorotate: Bool {

        if topViewController != nil && (topViewController?.isKind(of: LogInViewController.self))!
        {
            return true
        }
        return false
    }

    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {

        if topViewController != nil && (topViewController?.isKind(of: LogInViewController.self))!
        {
            return .portrait
        }
        return .landscapeRight

    }
    override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {

        if topViewController != nil && (topViewController?.isKind(of: LogInViewController.self))!
        {
            return .portrait
        }
        return .landscapeRight
    }
}

An der Stelle LoginViewController, die UIViewControllerSie zeigen möchten. In meinem Fall möchte ich das LoginViewControllerim PortraitModus andere ViewControllersim landscapeModus anzeigen.

Ramakrishna
quelle
-1

Bitte verwenden Sie die folgende Methode, um dieses Problem zu lösen

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

gib nur die Orientierung zurück, die du willst !!!

maxfiresolutions
quelle
3
Ich habe das getan, wie ich geschrieben habe. Dies verhindert, dass sich mein Ansichts-Controller dreht, zwingt ihn jedoch nicht in die einzig unterstützte Ausrichtung zurück, wenn ich zu ihm zurückkehre.
Harald Bögeholz
Das funktioniert bei mir nicht. Selbst wenn ich dies in meinen Ansichts-Controller aufgenommen habe, dreht sich die Ansicht immer noch. Was gibt?
Shim
Warum für maxfiresolutions abstimmen? Es hat bei mir funktioniert und die gleiche Methode von @Flo hat viele positive Stimmen.
ViruMax