In meiner Implementierung habe ich die UIView für meine Ansicht subclassiert, die ich drehen möchte und so etwas wie viewController für diese Ansicht, die nur eine Unterklasse von NSObject ist.
In diesem ViewController mache ich alle Prüfungen in Bezug auf Änderungen der Ausrichtung, Entscheidung, ob ich die Ausrichtung meiner Zielansicht ändern sollte, und wenn ja, dann rufe ich Methode meiner Ansicht für die Änderung der Ausrichtung.
Als Erstes müssen wir die Ausrichtung der gesamten Anwendungsoberfläche im Hochformatmodus korrigieren, so dass unsere ACCaptureVideoPreviewLayer immer still bleibt. Dies ist in den MainViewController.h
getan:
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation`
{
return interfaceOrientation==UIInterfaceOrientationPortrait;
}
Es gibt NO zu allen Orientierungen außer Portrait.
Um unsere eigenen Viewcontroller der Lage sein, die Änderungen der Geräteausrichtung verfolgen wir einen Beobachter von entsprechenden Mitteilungen machen müssen:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(orientationChanged) name:UIDeviceOrientationDidChangeNotification object:nil];
ich diese Zeilen in der (void)awakeFromNib
Methode meiner Viewcontroller setzen. Jedes Mal, wenn die Geräteausrichtung geändert wird, wird die ViewController-Methode orientationChanged
aufgerufen.
Sein Zweck ist es zu überprüfen, was die neue Ausrichtung des Geräts ist, was die letzte Ausrichtung des Geräts war und entscheiden, ob es geändert werden soll. Hier ist die Umsetzung:
if(UIInterfaceOrientationPortraitUpsideDown==[UIDevice currentDevice].orientation ||
lastOrientation==(UIInterfaceOrientation)[UIDevice currentDevice].orientation)
return;
[[UIApplication sharedApplication]setStatusBarOrientation:[UIDevice currentDevice].orientation animated:NO];
lastOrientation=[UIApplication sharedApplication].statusBarOrientation;
[resultView orientationChanged];
Wenn die Ausrichtung ist das gleiche wie zuvor oder in PortraitUpsideDown dann nichts zu tun. Andernfalls wird die Statusleistenausrichtung auf die richtige eingestellt, sodass bei einem eingehenden Anruf oder einer Verknöcherung auf der rechten Seite des Bildschirms angezeigt wird. Und dann rufe ich auch method in der Zielansicht auf, wo alle entsprechenden Änderungen für die neue Orientierung vorgenommen werden, wie rotieren, skalieren, die anderen Elemente der Schnittstelle in dieser Ansicht entsprechend der neuen Orientierung verschieben. Hier
ist die Umsetzung des orientationChanged
in Zielansicht:
Float32 angle=0.f;
UIInterfaceOrientation orientation=[UIApplication sharedApplication].statusBarOrientation;
switch (orientation) {
case UIInterfaceOrientationLandscapeLeft:
angle=-90.f*M_PI/180.f;
break;
case UIInterfaceOrientationLandscapeRight:
angle=90.f*M_PI/180.f;
break;
default: angle=0.f;
break;
}
if(angle==0 && CGAffineTransformIsIdentity(self.transform)) return;
CGAffineTransform transform=CGAffineTransformMakeRotation(angle);
[UIView beginAnimations:@"rotateView" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:0.35f];
self.transform=transform;
[UIView commitAnimations];
Natürlich hier können Sie weitere Änderungen wie Übersetzung hinzufügen, Skalierung verschiedener Ansichten Ihrer Schnittstelle, die neue Ausrichtung reagieren müssen und animieren Sie.
Auch Sie brauchen nicht den ViewController dafür, aber tun Sie alle nur in der Klasse Ihrer Ansicht. Hoffe, dass die allgemeine Idee klar ist.
Vergessen Sie auch nicht immer Benachrichtigung zu stoppen für die Orientierung ändert, wenn Sie sie nicht brauchen mag:
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
[[UIDevice currentDevice]endGeneratingDeviceOrientationNotifications];
Hatte ähnliches Problem. Eine _obvious_ Lösung ist leider nicht verfügbar: ich hatte gehofft (mit KVO) 'transform' von' viewslayer' der Ansichtsschicht ohne Glück zu beobachten - Schlüssel-Wert-Beobachtung ist während der Animationslaufzeit nicht verfügbar. Beendet mit (wahrscheinlich) der gleichen Lösung wie Sie: Preview Layer in eine 'UIView' einbetten und manuell rotieren. –
Ja, ich endete auch mit der manuellen Drehung der Ansicht, die den previewLayer enthält. Es stellte sich heraus, dass es nicht sehr kompliziert war. Ich wenden CGAffineTransformMakeRotation() an und ändern dann den Rahmen auf die richtige Größe. Aber jetzt habe ich genau das Verhalten, das ich will. – BartoNaz
@BartoNaz Ich habe seit ein paar Tagen damit zu kämpfen und alles, was ich versuche, gibt mir nicht den Effekt der camera.app, wo die AVCaptureVideoPreviewLayer auf eine Ansicht gesperrt bleibt, und ihre animierte Rotation nicht macht. Könnten Sie bitte Ihr Arbeitscode-Snippet als Antwort auf diese Frage bereitstellen? Vielen Dank. –