在我的實現中,我已經爲我的視圖子類化了我想要旋轉的UIView,以及像viewController這樣的視圖,它只是NSObject的一個子類。
在這個viewController中,我做了所有與定位變化有關的檢查,決定是否應該改變目標視圖的方向,如果是,那麼我調用我的視圖方法來改變它的方向。
首先,我們需要將整個應用程序界面的方向修改爲肖像模式,以便我們的ACCaptureVideoPreviewLayer始終保持靜止。 這是在做MainViewController.h
:
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation`
{
return interfaceOrientation==UIInterfaceOrientationPortrait;
}
它NO返回到所有方向,除了人像。
爲了我們的自定義的viewController能夠跟蹤設備的方向,我們需要讓相應的通知觀察員變化:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(orientationChanged) name:UIDeviceOrientationDidChangeNotification object:nil];
我把這些線在我的viewController的(void)awakeFromNib
方法。 所以每當設備方向改變時,viewController的方法orientationChanged
將被調用。
其目的是檢查設備的新方向是什麼,設備的最後方向是什麼,並決定是否改變它。這裏是執行:
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];
如果方向與以前相同或在PortraitUpsideDown中則不做任何事情。 否則,它會將狀態欄方向設置爲正確的方向,以便在有來電或骨化時它會出現在屏幕的正確一側。然後我在目標視圖中調用方法,其中新方向的所有相應更改都已完成,例如旋轉,調整大小,移動此視圖中與新方向對應的其他界面元素。
這裏是orientationChanged
的目標視圖的實現:
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];
當然,在這裏你可以添加任何其他更改,如翻譯,那需要應對新的方向和動畫的接口的不同視圖縮放他們。
此外,您可能不需要viewController,但只需在視圖的類中進行操作即可。 希望總體思路清晰。
也不要忘記了方向將更改爲停止收到通知時,你不需要他們喜歡:
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
[[UIDevice currentDevice]endGeneratingDeviceOrientationNotifications];
曾有類似的問題。一個_obvious_解決方案令人遺憾地不可用:我希望觀察(使用KVO)視圖的圖層'presentationLayer'的轉換,而沒有運氣 - 在動畫運行時鍵值觀察不可用。結束時使用(可能)相同的解決方案:嵌入預覽圖層到一個'UIView'手動旋轉它。 –
是的,我最終還是手動旋轉了包含previewLayer的視圖。事實證明,這不是很複雜。我應用CGAffineTransformMakeRotation(),然後將框架更改爲正確的大小。但現在我完全有我想要的行爲。 – BartoNaz
@BartoNaz我一直在爲此奮鬥了幾天,我所嘗試的一切都沒有給出camera.app的效果,AVCaptureVideoPreviewLayer保持鎖定視圖,並且不會執行動畫旋轉。你能否提供你的工作代碼片段作爲這個問題的答案?謝謝。 –