在我的实现中,我为想要旋转的视图子类化了UIView,并为该视图创建了一个类似于viewController的对象,它只是NSObject的子类。
在这个viewController中,我进行所有与方向变化相关的检查,决定是否应该更改目标视图的方向,如果是,则调用我的视图方法来更改其方向。
首先,我们需要将整个应用程序界面的方向固定为竖屏模式,以便我们的ACCaptureVideoPreviewLayer始终保持静止。这是在MainViewController.h文件中完成的:
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation`
{
return interfaceOrientation==UIInterfaceOrientationPortrait;
}
除了纵向模式,它会对所有方向返回NO。
为了使我们的自定义视图控制器能够跟踪设备方向的变化,我们需要将其设置为相应通知的观察者:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(orientationChanged) name:UIDeviceOrientationDidChangeNotification object:nil]
我将这些行放在我的视图控制器的
(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];
如果方向与之前相同或为“竖直向下”,则不执行任何操作。否则,它会将状态栏方向设置为正确的方向,以便在有来电或 ossification 时,它将显示在屏幕的正确侧面。然后我还要调用目标视图中的方法,以执行所有新方向相关的对应更改,如旋转、调整大小、移动此视图中其他接口元素的位置等。
以下是目标视图中
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]
transform
,但是没有成功——在动画运行时无法使用键值观察。最终采用了与您可能相同的解决方案:将预览层嵌入到一个UIView
中并手动旋转它。 - Rok Jarc