it-swarm.com.de

IOS 6 Erzwingen Sie die Ausrichtung des Geräts in die Landschaft

Ich gab eine App mit 10 View-Controllern. Ich benutze den Navigationscontroller, um sie zu laden/entladen. 

Alle außer einem sind im Hochformat. Angenommen, der 7. VC befindet sich in einer Landschaft. Ich brauche es, um in Landschaft dargestellt zu werden, wenn es geladen wird. 

Bitte schlagen Sie einen Weg vor, um die Ausrichtung in IOS 6 von Portrait zu Landschaft zu zwingen (und es ist gut, auch in IOS 5 zu arbeiten).

So habe ich es gemachtVORIOS 6:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    UIViewController *c = [[[UIViewController alloc]init] autorelease];
    [self presentModalViewController:c animated:NO];
    [self dismissModalViewControllerAnimated:NO];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

Durch die Präsentation und Ablehnung eines Modals VC musste die App ihre Ausrichtung überprüfen. Daher wurde shouldAutorotateToInterfaceOrientation aufgerufen.

Was ich in IOS 6 versucht habe:

- (BOOL)shouldAutorotate{
    return YES;
}
-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
    return UIInterfaceOrientationLandscapeLeft;
}

Unter Last bleibt der Controller im Portrait. Nach dem Drehen des Geräts ändert sich die Ausrichtung einfach. Aber ich muss den Controller so einstellen, dass er sich beim Laden automatisch in die Querformat dreht, sodass der Benutzer das Gerät drehen muss, um die Daten richtig zu sehen.

Ein weiteres Problem: Nach dem Zurückdrehen des Geräts auf Hochformat geht die Ausrichtung auf Hochformat, obwohl ich in supportedInterfaceOrientations nur UIInterfaceOrientationMaskLandscape angegeben habe. Warum passiert es?

Außerdem werdenNONEvon über 3 Methoden aufgerufen.

Einige (nützliche) Daten:

  1. In meiner Plist-Datei habe ich 3 Orientierungen angegeben - alle auf dem Kopf stehend.
  2. Das Projekt wurde in Xcode 4.3 IOS 5 gestartet. Alle Klassen einschließlich Xibs wurden vor Xcode 4.5 IOS 6 erstellt. Jetzt verwende ich die letzte Version.
  3. In der plist-Datei ist die Statusleiste sichtbar.
  4. In der xib-Datei (die ich im Querformat sein möchte) ist die Statusleiste "Keine". Die Ausrichtung ist auf Querformat festgelegt.

Jede Hilfe wird geschätzt. Vielen Dank. 

57
John Smith

Ok, Leute, ich werde meine Lösung posten.

Was ich habe:

  1. Eine View-basierte Anwendung mit mehreren View-Controllern. (Es war navigationsbasiert, aber aufgrund von Orientierungsproblemen musste ich es auf Ansichtsbasis erstellen.).
  2. Alle Ansichts-Controller sind Hochformat, mit Ausnahme eines - LandscapeLeft.

Aufgaben:

  1. Einer meiner View-Controller muss automatisch in die Landschaft gedreht werden, unabhängig davon, wie der Benutzer das Gerät hält. Alle anderen Controller müssen im Hochformat sein. Nach dem Verlassen des Landschaftscontrollers muss die App zwingen, in Hochformat zu drehen, unabhängig davon, wie der Benutzer das Gerät hält.
  2. Dies muss unter IOS 6.x wie unter IOS 5.x funktionieren

Gehen!

(Update Die von @Ivan Vučica vorgeschlagenen Makros wurden entfernt.)

In allen PORTRAIT-View-Controllern überschreiben Sie Autorotationsmethoden wie folgt:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{
    return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}
-(BOOL)shouldAutorotate {
    return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

Sie können die zwei Ansätze sehen: einen für IOS 5 und einen anderen für IOS 6.

Dasselbe gilt für Ihren LANDSCAPE-View-Controller mit einigen Ergänzungen und Änderungen: 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{
    [image_signature setImage:[self resizeImage:image_signature.image]];
    return (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
-(BOOL)shouldAutorotate {
    return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
    [image_signature setImage:[self resizeImage:image_signature.image]];
    return UIInterfaceOrientationMaskLandscapeLeft;
}

ACHTUNG: Um die Autorotation in IOS 5 zu erzwingen, müssen Sie Folgendes hinzufügen:

- (void)viewDidLoad{
    [super viewDidLoad];
    if ([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0)
        [[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:NO];    
}

Analog dazu sollten Sie nach Verlassen des LANDSCAPE-Controllers unabhängig von dem geladenen Controller erneut die Autorotation für IOS 5 erzwingen. Jetzt werden Sie jedoch UIDeviceOrientationPortrait verwenden, während Sie zu einem PORTRAIT-Controller wechseln:

- (void)viewDidLoad{
        [super viewDidLoad];
        if ([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0)
            [[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationPortrait animated:NO];    
    }

Nun das letzte (und es ist ein bisschen komisch) - Sie müssen die Art ändern, wie Sie von einem Controller zu einem anderen wechseln, abhängig von der IOS:

Machen Sie eine NSObject-Klasse "Schalter". 

In Schalter.h sagen Sie:

#import <Foundation/Foundation.h>

@interface Schalter : NSObject
+ (void)loadController:(UIViewController*)VControllerToLoad andRelease:(UIViewController*)VControllerToRelease;
@end

In Schalter.m sagen Sie:

#import "Schalter.h"
#import "AppDelegate.h"

@implementation Schalter
+ (void)loadController:(UIViewController*)VControllerToLoad andRelease:(UIViewController*)VControllerToRelease{

    //adjust the frame of the new controller
    CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
    CGRect windowFrame = [[UIScreen mainScreen] bounds];
    CGRect firstViewFrame = CGRectMake(statusBarFrame.Origin.x, statusBarFrame.size.height, windowFrame.size.width, windowFrame.size.height - statusBarFrame.size.height);
    VControllerToLoad.view.frame = firstViewFrame;

    //check version and go
    if (IOS_OLDER_THAN_6)
        [((AppDelegate*)[UIApplication sharedApplication].delegate).window addSubview:VControllerToLoad.view];
    else
        [((AppDelegate*)[UIApplication sharedApplication].delegate).window setRootViewController:VControllerToLoad];

    //kill the previous view controller
    [VControllerToRelease.view removeFromSuperview];
}
@end

JETZT, so verwenden Sie Schalter (angenommen, Sie gehen vom Warehouse-Controller zum Products-Controller):

#import "Warehouse.h"
#import "Products.h"

@implementation Warehouse
Products *instance_to_products;

- (void)goToProducts{
    instance_to_products = [[Products alloc] init];
    [Schalter loadController:instance_to_products andRelease:self];
}

bla-bla-bla your methods

@end

Natürlich müssen Sie instance_to_products Objekt freigeben:

- (void)dealloc{
     [instance_to_products release];
     [super dealloc];
}

Nun, das ist es. Zögern Sie nicht, abzustimmen, das ist mir egal. Dies ist für diejenigen, die nach Lösungen suchen, nicht nach Ansehen. Prost! Sava Mazare.

43
John Smith

Dies sollte funktionieren, es ähnelt der Version vor iOS 6, jedoch mit einer UINavigationController:

UIViewController *portraitViewController = [[UIViewController alloc] init];
UINavigationController* nc = [[UINavigationController alloc] initWithRootViewController:portraitViewController];
[self.navigationController presentModalViewController:nc animated:NO];
[self.navigationController dismissModalViewControllerAnimated:NO];

Ich rufe das an, bevor ich die nächste UIViewController schiebe. Dadurch wird erzwungen, dass die nächste gedrückte UIViewController im Hochformatmodus angezeigt wird, auch wenn sich die aktuelle UIViewController im Querformat befindet (sollte auch für Portrait to Landscape funktionieren). Funktioniert auf iOS 4 + 5 + 6 für mich.

34
Chunkylover53

Ich denke, die beste Lösung besteht darin, sich an die offizielle Apple-Dokumentation zu halten. Dementsprechend verwende ich folgende Methoden und alles funktioniert sehr gut auf iOS 5 und 6. In meinem VC überschreibe ich folgende Methoden:

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

Methoden für iOS 6, erste Methode gibt unterstützte Orientierungsmaske zurück (wie der Name schon sagt)

-(NSUInteger)supportedInterfaceOrientations{

    return UIInterfaceOrientationMaskPortrait;
}

das zweite sagt Ihrem VC, welche bevorzugte Ausrichtung der Schnittstelle ist, wenn VC angezeigt wird. 

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationPortrait;
}

Ändern Sie einfach das Portrait, um die gewünschte Orientierung zu erhalten;) Diese Lösung funktioniert reibungslos. Ich mag die Idee, Makros und andere Dinge zu erstellen, nicht. Ich hoffe das hilft...

14
Skodik.o

Ich hatte das gleiche Problem, 27 Ansichten in meiner Anwendung, von denen 26 im Hochformat und nur eine in allen Ausrichtungen (ein Bildbetrachter :)). Das Hinzufügen des Makros in jeder Klasse und das Ersetzen der Navigation war keine Lösung, die ich war bequem mit ...

Ich wollte also die UINavigationController-Mechanik in meiner App behalten und diese nicht durch anderen Code ersetzen.

Was ist zu tun:

@ 1 In der Anwendung delegieren Sie in der Methode didFinishLaunchingWithOptions

if ([[UIDevice currentDevice].systemVersion floatValue] < 6.0)
{
    // how the view was configured before IOS6
    [self.window addSubview: navigationController.view];
    [self.window makeKeyAndVisible];
}
else
{
    // this is the code that will start the interface to rotate once again
    [self.window setRootViewController: self.navigationController];
}

@ 2 Da der navigationController nur mit YES zur Autorotation antwortet, müssen einige Einschränkungen hinzugefügt werden: Erweitern Sie den UINavicationController -> YourNavigationController und verknüpfen Sie ihn mit dem Interface Builder.

@ 3 Überschreiben Sie die "neuen Methoden" vom Navigationscontroller.

Da diese Klasse nur für diese Anwendung benutzerdefiniert ist, kann sie die Verantwortung für ihre Controller übernehmen und an ihrer Stelle reagieren.

-(BOOL)shouldAutorotate {

    if ([self.viewControllers firstObject] == YourObject)
    {
         return YES;
    }
    return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
     if ([self.viewControllers firstObject] == YourObject)
    {
         return UIINterfaceOrientationMaskLandscape;
    }
    return UIInterfaceOrientationMaskPortrait;
}

Ich hoffe, dies wird dir helfen, 

7
Vlad Cioaba

Aus den iOS 6 Versionshinweisen :

IOS-Container (z. B. UINavigationController) konsultieren ihre Kinder jedoch nicht, um zu bestimmen, ob sie sich automatisch drehen sollen.

Übergibt Ihre rootViewController die shouldAutoRotate-Nachricht die ViewController-Hierarchie an Ihren VC?

3
sjwarner

Ich habe die gleiche Methode wie OP pre-ios6 verwendet (einen modalen VC präsentieren und abweisen), um einen einzelnen View-Controller im Querformatmodus anzuzeigen (alle anderen im Hochformat). In ios6 brach es mit der Landschaft VC im Hochformat ein.

Um das Problem zu beheben, habe ich gerade die preferredInterfaceOrientationForPresentation-Methode im Querformat-VC hinzugefügt. Scheint für os 5 und os 6 gut zu funktionieren.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

- (BOOL)shouldAutorotate
{
return NO;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{    
return UIInterfaceOrientationLandscapeLeft;
}
2
user1581123

Hey Leute, nachdem ich viele verschiedene mögliche Lösungen ohne Erfolg versucht hatte, kam ich mit der folgenden Lösung heraus, hoffe es hilft !. 

Ich habe ein Rezept vorbereitet :).

Problem: Sie müssen die Orientierung der Viewcontroller mithilfe des Navigationscontrollers in iOS 6 ändern. 

Lösung:

navigation suggested

step 1. Ein erster UIviewcontroler, um modale Segmente in Landscape und .__ auszulösen. Porträt UInavigationControllers als Bild zeigt ....

tiefer in UIViewController1 brauchen wir 2 verschiedene Aktionen nach globalen Variablen bei Appdelegate ...

-(void)viewDidAppear:(BOOL)animated{
    if([globalDelegate changeOrientation]==0){
        [self performSegueWithIdentifier:@"p" sender:self];
    }
    else{
        [self performSegueWithIdentifier:@"l" sender:self];
    }

}

auch brauchen wir einen Weg zurück zum Portrait & | Landschaft....

- (IBAction)dimis:(id)sender {
    [globalDelegate setChangeOrientation:0];
    [self dismissViewControllerAnimated:NO completion:nil];
}

step 2. der erste Pushed UiViewController an jedem NavigationController geht mit...

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

-(BOOL)shouldAutorotate{
    return YES;
}

step 3. Die unterstützteInterfaceOrientations-Methode wird in der Unterklasse von UInavigationController überschrieben.

in Ihrem customNavigationController haben wir .....

-(NSUInteger)supportedInterfaceOrientations{
    if([self.visibleViewController isKindOfClass:[ViewController2 class]]){

        return UIInterfaceOrientationMaskPortrait;
    }
    else{
        return UIInterfaceOrientationMaskLandscape;

    }

}

step 4. Im Storyboard oder nach Code setzen Sie das Zeichen wantFullScreenLayout auf yes, sowohl im Hochformat als auch im Querformat. 

2
47tucanae

Versuchen Sie, zu einer UINavigationController zu wechseln, die eine Kategorie verwendet oder eine Unterklasse enthält, um die gewünschte Ausrichtung festzulegen, und wechseln Sie dann zum gewünschten VC. Lesen Sie mehr hier .

1
Michael Mangold

Alternativ können Sie dasselbe mit Blöcken tun:

UIViewController *viewController    = [[UIViewController alloc] init];
viewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:viewController animated:NO completion:^{
    [self dismissViewControllerAnimated:NO completion:nil];
}];

Rufen Sie es auch auf, bevor Sie die neue Ansicht aufrufen.

1
Raspu

Ich hatte das gleiche Problem. Wenn Sie die Anzeige eines bestimmten View-Controllers im Querformat erzwingen möchten, führen Sie ihn direkt aus, bevor Sie ihn in den Navigations-Stack verschieben.

UIInterfaceOrientation currentOrientation = [[UIApplication sharedApplication] statusBarOrientation];
        if (currentOrientation == UIInterfaceOrientationPortrait ||
            currentOrientation == UIInterfaceOrientationPortraitUpsideDown)
            [[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeLeft];

        UIViewController *vc = [[UIViewController alloc] init];
        [self.navigationController pushViewController:vc animated:YES];
        [vc release];
0
Norbert Antal

Ich habe es gelöst, indem ich UINavigationController subclassing und die unterstützten InterfaceOrientations des Navigationscontrollers wie folgt überschreibt:

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

Alle Controller implementierten unterstütztInterfaceOrientations mit ihren gewünschten Ausrichtungen.

0
Zeev Vax

Gehen Sie zu Ihrer Info.plist-Datei und nehmen Sie die Änderung vor enter image description here