2009-04-08 7 views
7

Ich möchte folgendes implementieren. Wenn der Benutzer das iPhone dreht, möchte ich einen neuen UIViewController instanziieren (automatisch beim Drehen, nicht auf eine Schaltfläche klicken oder eine ähnliche Aktion ausführen) und dem Benutzer eine Ansicht anzeigen, die von diesem neuen UIViewController im Querformat gehandhabt wird. Wie mache ich das richtig?Das iPhone rotieren und einen neuen UIViewController instanziieren?

Ich habe versucht, den neuen Controller in den Methoden willRotateToInterfaceOrientation und didRotateFromInterfaceOrientation zu instanziieren, aber keine dieser Methoden wird aufgerufen !. Ich vermute, das liegt daran, dass der aktuelle Controller von einem Navigationscontroller eingedrungen ist, der selbst von einem tabBarController bedient wird. Irgendeine Ahnung? Ein einfaches Code-Snippet würde sehr geschätzt werden.

Vielen Dank im Voraus.

Antwort

7

Ich habe diese genaue Art von Verhalten in einer App implementiert und der Schlüssel ist sicherzustellen, dass alle übergeordneten Controller shouldAutorotateToInterfaceOrientation implementieren und dass Ihr aktueller View-Controller es auch implementiert. In meinem Fall verwende ich einen Tab-Controller, der den Aufruf von sentAutorotateToInterfaceOrientation abfängt, und ich musste den Tab-Controller außer Kraft setzen, damit der Anruf durchfällt. Das Standardverhalten von Ansichtscontrollern wird nur im Hochformat angezeigt.

So müssen Sie sie zwingen, alle Orientierung zu ermöglichen, ändert sich durch: - (BOOL) ShouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation { return YES; }

Dann, um einen neuen View-Controller laden Sie reagieren sollen:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 
    if((fromInterfaceOrientation == UIInterfaceOrientationPortrait) || 
    (fromInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)) 
    {  
    // Load the view controller you want to display in landscape mode... 
    } 
} 

und kann auch verwendet werden:

-(void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 

erkennen, dass die Orientierungsänderung kommt.

In meinem Fall verwende ich didRotateFromInterfaceOrientation, um zu überprüfen, ob die letzte Ausrichtung Hochformat war, und wenn ja, lade die Ansicht, die ich im Querformat anzeigen möchte.

Ich habe dann die gleichen Methoden im Viewcontroller implementiert, den ich lade, und es ist verantwortlich für das Erkennen, wenn die Ausrichtung zurück in Hochformat wechselt und sich vom Ansichtsstapel ablöst.

Hoffe, dass hilft ein wenig.

Paul

+0

Muss ich die ursprüngliche tabBarController ableiten, um die Methode shaotAutorotateToInterfaceOrientation hinzuzufügen? Dieser TabBar-Controller wurde unter Verwendung von IB und einigen Zeilen eines Codes im Anwendungsdelegaten eingerichtet. Ich habe alle Schritte befolgt, aber didRotateFromInterfaceOrientation wurde nicht aufgerufen. –

+1

Ok, ich habe den tabBarController subclassiert, indem ich shouldAutorotateToInterfaceOrientation hinzugefügt habe und nun alles funktioniert. Vielen Dank für Ihre Hilfe. Mit freundlichen Grüßen. –

+0

Ich bevorzuge überhaupt nicht UITabBarController und stattdessen einen UIViewController mit einer UITabBar. – mk12

1

Implementieren Sie shouldAutorotateToInterfaceOrientation? Wenn nicht, dann könnten Sie die Nachrichten nicht erhalten.

+0

Ja ich. Auch wenn YES einfach zurückgeschickt wird, funktioniertAutorotateToInterfaceOrientation nicht. –

29

Eine sauberere Art und Weise ist nicht UIInterfaceOrientation für die Rotation zu verwenden.

Warum, weil dann Ihre Schnittstelle oder Ansicht 1 tatsächlich rotiert. Dies bedeutet, dass Sie es zurückdrehen müssen, um es wieder anzuzeigen, nachdem die Ansicht 2 entfernt wurde.

Um dies zu kompensieren, ich einfach abonnieren UIDeviceOrientation Benachrichtigungen. Ganz anders. Ansicht 1 muss die Autorotation NICHT unterstützen, damit diese Methode funktioniert.In viewDidLoad geben Sie den folgenden Code ein:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(detectOrientation) name:@"UIDeviceOrientationDidChangeNotification" object:nil]; 

Dann definieren Sie einfach die Methode detectOrientation: weder Ihrer Ansichten

-(void) detectOrientation { 

    if (([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) || 
      ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight)) { 

     //load view 2 


    } else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait) { 

     // load view 1 

    } 
} 

Jetzt brauchen Unterstützung autoratation! Sie müssen jedoch auf eine auf Sicht 2 vor dem Laden Transformation durchführen:

-(void) transformView2ToLandscape { 

    NSInteger rotationDirection; 
    UIDeviceOrientation currentOrientation = [[UIDevice currentDevice] orientation]; 

    if(currentOrientation == UIDeviceOrientationLandscapeLeft){ 
    rotationDirection = 1; 
    }else { 
    rotationDirection = -1; 
    } 

    CGRect myFrame = CGRectMake(0, 0, 480, 300); 
    CGAffineTransform transform = [[self view2] transform]; 
    transform = CGAffineTransformRotate(transform, degreesToRadians(rotationDirection * 90)); 
    [[self view2] setFrame: myFrame]; 
    CGPoint center = CGPointMake(myFrame.size.height/2.0, myFrame.size.width/2.0); 
    [[self view2] setTransform: transform]; 
    [[self view2] setCenter: center]; 

} 

Das ist, wie ich tauschen Ansichten o Drehung ohne Eigendrehung Unterstützung in meinen Ansichten.

+1

Das sieht wirklich interessant aus. Ich werde versuchen, die tatsächliche Leistung zu verstehen, d. H. Wie viel schneller eine Benachrichtigung geliefert wird und wie viel Zeit benötigt wird, um die Transformation anzuwenden. Vielen Dank. –

+0

das funktioniert sehr gut. speziell wenn Sie zwei verschiedene View-Controller für zwei Ausrichtungen verwenden. –

+0

Die "checked" Antwort beantwortet die Frage, aber diese Antwort beantwortet die Frage, die (idealerweise) hätte gestellt werden sollen. – DBD

3

Tatsächlich wird nur der Controller der obersten Ebene benachrichtigt. Sie sind dafür verantwortlich, verschachtelte Controller zu benachrichtigen.

Fügen Sie diese auf der Tab-Leiste Controller:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { 
    [self.selectedViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation]; 
} 
+0

Danke, ich werde das zu meinem Code hinzufügen. –

+0

Sie sollten UITabBarController nicht unterklassifizieren. – mk12

+0

@ Mk12: Warum? Kann eine solche kleine Übersteuerung zu Problemen führen? – Kornel

Verwandte Themen